git clone https://github.com/elz-lang/elz.git
cd elz && cargo install
-
void
-
int
-
f64
-
bool
-
string
-
List[T]
TODO: #200
- Variable
- Function
- Class
- Trait, TODO: #241, #225, #250
Take a look at CHANGELOG
A polymorphism object-oriented programming language
License: MIT License
git clone https://github.com/elz-lang/elz.git
cd elz && cargo install
void
int
f64
bool
string
List[T]
TODO: #200Take a look at CHANGELOG
Make sure you have clang(the point is generated LLVM layout, so you, of course, can use other things)
Create a C file had use printf
// main.c
#include <stdio.h>
int main() {
printf("Print something: %s", "Another string");
}
Then use clang -S -emit-llvm main.c
compile it. You will get something like:
; ModuleID = 'main.c'
source_filename = "main.c"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.13.0"
@.str = private unnamed_addr constant [20 x i8] c"Print something: %s\00", align 1
@.str.1 = private unnamed_addr constant [15 x i8] c"Another string\00", align 1
; Function Attrs: noinline nounwind optnone ssp uwtable
define i32 @main() #0 {
%1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.1, i32 0, i32 0))
ret i32 0
}
declare i32 @printf(i8*, ...) #1
attributes #0 = { noinline nounwind optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"PIC Level", i32 2}
!2 = !{!"clang version 6.0.0 (tags/RELEASE_600/final)"}
Copy printf
declaration into your IR code. Then try it.
ps. It just a experimental way to detect how can it work, not good solution
As title, because elz
wants no GC, but automatic manage the memory, so we have to create an abstract system to do that.
At least:
Following code should be seen as executable form.
fn main() {}
As title
Like these mod1::fn1
, mod1::fn2
As title, the message in CONTRIBUTING.md is wrong.
As title, incompatible type, need to read LLVM doc then rewrite that.
elz: ../../../../../include/llvm/Support/Casting.h:255: typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X = llvm::Constant; Y = llvm::Value; typename llvm::cast_retty<X, Y*>::ret_type = llvm::Constant*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
SIGABRT: abort
PC=0x7fc76fe19428 m=0 sigcode=18446744073709551610
signal arrived during cgo execution
goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x541db0, 0xc4200f1d80, 0x2865ce8)
/usr/lib/go-1.9/src/runtime/cgocall.go:132 +0xe4 fp=0xc4200f1d50 sp=0xc4200f1d10 pc=0x419894
llvm.org/llvm/bindings/go/llvm._Cfunc_LLVMConstFMul(0x2865c10, 0x2867ee8, 0x0)
llvm.org/llvm/bindings/go/llvm/_obj/_cgo_gotypes.go:2853 +0x4e fp=0xc4200f1d80 sp=0xc4200f1d50 pc=0x4f433e
llvm.org/llvm/bindings/go/llvm.ConstFMul.func1(0x2865c10, 0x2867ee8, 0x2865110)
/home/routedan/workspace/go/src/llvm.org/llvm/bindings/go/llvm/ir.go:870 +0xa3 fp=0xc4200f1db8 sp=0xc4200f1d80 pc=0x4f6853
llvm.org/llvm/bindings/go/llvm.ConstFMul(0x2865c10, 0x2867ee8, 0x2867ee8)
/home/routedan/workspace/go/src/llvm.org/llvm/bindings/go/llvm/ir.go:870 +0x35 fp=0xc4200f1de0 sp=0xc4200f1db8 pc=0x4f5a05
github.com/elz-lang/elz/ast.(*BinaryExpr).Codegen(0xc420133080, 0xc420132fc0, 0xc42011e3d4)
/home/routedan/workspace/go/src/github.com/elz-lang/elz/ast/expr.go:41 +0x12c fp=0xc4200f1e30 sp=0xc4200f1de0 pc=0x4f758c
github.com/elz-lang/elz/ast.(*VarDefination).Codegen(0xc420126f80, 0xc420132fc0, 0x2867e28)
/home/routedan/workspace/go/src/github.com/elz-lang/elz/ast/ast.go:34 +0xb5 fp=0xc4200f1e88 sp=0xc4200f1e30 pc=0x4f70e5
github.com/elz-lang/elz/listener.(*ElzListener).Module(0xc420126ec0, 0x90c0c0)
/home/routedan/workspace/go/src/github.com/elz-lang/elz/listener/listener.go:27 +0x5b fp=0xc4200f1ef0 sp=0xc4200f1e88 pc=0x53c62b
main.main()
/home/routedan/workspace/go/src/github.com/elz-lang/elz/main.go:23 +0x203 fp=0xc4200f1f80 sp=0xc4200f1ef0 pc=0x53f553
runtime.main()
/usr/lib/go-1.9/src/runtime/proc.go:195 +0x226 fp=0xc4200f1fe0 sp=0xc4200f1f80 pc=0x441776
runtime.goexit()
/usr/lib/go-1.9/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc4200f1fe8 sp=0xc4200f1fe0 pc=0x46a501
rax 0x0
rbx 0x7fc7748da000
rcx 0x7fc76fe19428
rdx 0x6
rdi 0x2b76
rsi 0x2b76
rbp 0x7fc770ebb0f8
rsp 0x7ffcd4dcc638
r8 0xfefefefefefefeff
r9 0x1
r10 0x8
r11 0x202
r12 0xff
r13 0x7fc770ee46e0
r14 0x13
r15 0xc
rip 0x7fc76fe19428
rflags 0x202
cs 0x33
fs 0x0
gs 0x0
[add]: create a new file or add a new function.
[feat]: create a new feature. !!! A known feature, if not, create an issue then implement it
[fix]: Fixed known bug, !!! If this bug is an unknown bug, please create an issue then fixed it.
[clean]: comment, reformat(gofmt only), refactor. Include improving tests
[test]: new test
i8
*i32
*i64
*u8
u16
u32
u64
f32
*f64
*[V; len]
as arr<V, len>
, machine type?str
**
mean more important than remains
Can convert arr<V, len>
to list<V>
with length len
Syntax: <result> = trunc <ty> <value> to <ty2> ; yields ty2
The ‘trunc’ instruction takes a value to trunc, and a type to trunc it to. Both types must be of integer types or vectors of the same number of integers. The bit size of the value must be larger than the bit size of the destination type, ty2. Equal sized types are not allowed.
The ‘trunc’ instruction truncates the high order bits in value and converts the remaining bits to ty2. Since the source size must be larger than the destination size, trunc cannot be a no-op cast. It will always truncate bits.
%X = trunc i32 257 to i8 ; yields i8:1
%Y = trunc i32 123 to i1 ; yields i1:true
%Z = trunc i32 122 to i1 ; yields i1:false
%W = trunc <2 x i16> <i16 8, i16 7> to <2 x i8> ; yields <i8 8, i8 7>
Syntax: <result> = zext <ty> <value> to <ty2> ; yields ty2
The ‘zext’ instruction takes a value to cast, and a type to cast it to. Both types must be of integer types or vectors of the same number of integers. The bit size of the value must be smaller than the bit size of the destination type, ty2.
The zext fills the high order bits of the value with zero bits until it reaches the size of the destination type, ty2.
When zero extending from i1, the result will always be either 0 or 1.
%X = zext i32 257 to i64 ; yields i64:257
%Y = zext i1 true to i32 ; yields i32:1
%Z = zext <2 x i16> <i16 8, i16 7> to <2 x i32> ; yields <i32 8, i32 7>
If you see a compilation error while compiling your code with Go 1.9.4 or later as follows,
go build llvm.org/llvm/bindings/go/llvm: invalid flag in #cgo LDFLAGS: -Wl,-headerpad_max_install_names you need to set up $CGO_LDFLAGS_ALLOW to allow a compiler to specify some linker options:
$ export CGO_LDFLAGS_ALLOW='-Wl,(-search_paths_first|-headerpad_max_install_names)'
We have three kinds of normal var form in Elz.
pi = 3.1415926
fn foo() {
let flag = 0
}
fn foo() {
let mut i = 0
}
Unfortunately, llir/llvm can not do something I want, and go-llvm binding has poor document.
I think should use C++ to write the translate part, but we can use Go write the remain part.
Because we can have a lot of block in the function, even function in the function. And the variable accessible only in function, we need to impl function context for the project.
Example:
fn main() {
let a = 1
let b = a
}
Like how to use antlr
How LLVM IR mapping to Elz
How ast::Codegen work with type system
ps. ast: Abstract Syntax Tree
As title, should fix
compile Test file meet error message(go runtime)
var panic: runtime error: invalid memory address or nil pointer dereference
As title, use a llvm.Value of variable as value is invalid
The problem is commit messages format
part didn't have changed line.
The problem is because the implementation just now will try to get the Type info we will have after codegen.
But those Type info is needed at parse time.
So we will get invalid address(the data structure we put vars even don't have Initialize)
Put parameter info into FnBuilder
Let it can generate correct AST
A util module, put something like Stack data structure.
As title
As title, type: num mapping to float64(double)
If it can be, then how do we make sure an external type really matches a trait or not?
And the trait syntax has a bug that uses exportor
in rule, it should be exportor?
, allow do not export it.
Antlr release 4.7.1, trying to update before elz: 0.0.1 release.
I see a lot of practices use p.addr
, allocate a stack for a parameter, then store the data into an address, final load data from these addresses.
Example of C:
define i32 @add(i32, i32) #0 {
%3 = alloca i32, align 4
%4 = alloca i32, align 4
store i32 %0, i32* %3, align 4
store i32 %1, i32* %4, align 4
%5 = load i32, i32* %3, align 4
%6 = load i32, i32* %4, align 4
%7 = add nsw i32 %5, %6
ret i32 %7
}
Original Code:
int add(int l, int r) {
return l + r;
}
If you think you meet a bug, here.
Can't compile elz because the problem from dependency
go build llvm.org/llvm/bindings/go/llvm: invalid flag in #cgo LDFLAGS: -Wl,-search_paths_first
Can not just generate the IR. It won't get value, only error.
In rule: ident
I think v0.0.1 should contain:
str
, num
, and it's basic operationstr
, num
num
, str
expressionEdit after 2018-1-30 12:24
main
to have a workable executableEdit after 2018-1-30 14:44
For example:
fn add(a, b: num) -> num {
return a + b
}
Elz:
type: programming
color: "#7eb4ed"
extensions:
- ".elz"
As title, and this feature should be released at v0.0.1.
For example:
fn add(lv: num, rv: num) -> num {
return lv + rv
}
Should be compile to
define float @add(float, float) {
ret %0 + %1 // not totally correct syntax, focus on concept
}
Because the solution: just panic
will let us can only find one problem at once.
And we hope compiler can list all error(at least not just one) for the user.
It will become the critical issue when we implemented all expression
Feature: report error logs
as
expression for i64, f64
fn main() {
let a = 1.2 + 3 // it will cause error
let b = 1.2 + 3 as f32 // this can pass
}
The example shows the result of this issue's want, as
expression can convert the expression to the convertible certain type.
TODO:
as
expression AST ~> ast/as_expr.go & following testA useful function call should impl as fast as can.
Because some error will cause generation's error, so if we can check these problems first, then we can avoid these panic.
I think create test flow from now on is important.
Else the code base will only become more and more complex.
Let testing won't contain f**king so much error report at there
The form should like:
x = 1
fn foo() {
println(x)
}
fn main() {
let x = 2
println(x) // 2, override outside scope
foo() // 1
}
At example/test.elz, var: 世界
And LLVM also update go-llvm, so maybe need to update it.
As title, str
should have +
, [id]
...
The reason is that seems LLVM is not pretty stable(go-llvm only), I will add another choice that compiles to C++
. So that we can have an alternative to use when go-llvm
can't work.
The reason not Nim
but C++
is because already found some features of Nim
is not suit for elz
. For example, in Nim
, slice_a
equals to sliceA
, that is auto conversion. And method also is a problem, proc a(self: t)
let t
can't have a property call a
, but it should in elz
.
As title.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.