├── result.txt ├── test ├── type.expect ├── if.expect ├── recursive.expect ├── extend.expect ├── method.expect ├── array.expect ├── polymorphism.expect ├── heap.expect ├── args.expect ├── structfunc.expect ├── structvar.expect ├── method_args.expect ├── return_types.expect ├── types.expect ├── array.mugi ├── if.mugi ├── func.mugi ├── heap.mugi ├── args.mugi ├── recursive.mugi ├── structfunc.mugi ├── method.mugi ├── method_args.mugi ├── structvar.mugi ├── return_types.mugi ├── extend.mugi ├── types.mugi ├── polymorphism.mugi └── func.expect ├── script └── mugichac ├── src ├── ast.h.gch ├── func.h.gch ├── symbol.h.gch ├── type.h.gch ├── mugicha.h.gch ├── support.h.gch ├── callstack.h ├── mugicha.c ├── stack.h ├── mugicha.h ├── symbol.h ├── dynode.h ├── stack.c ├── func.h ├── symbol.c ├── func.c ├── type.h ├── support.h ├── type.c ├── mugicha_compiler.h ├── ast.h ├── mugicha.l ├── mugicha.y ├── llvm_builder.h ├── ast.c ├── llvm_builder.cpp ├── mugicha_compiler.cpp └── y.output ├── newsample.mugi ├── .gitignore ├── sample.mugi ├── args.mugi ├── ok_ver__sample.mugi ├── old_sample.mugi ├── readme.md └── Makefile /result.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/type.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/if.expect: -------------------------------------------------------------------------------- 1 | value = ok 2 | -------------------------------------------------------------------------------- /test/recursive.expect: -------------------------------------------------------------------------------- 1 | value = 120 2 | -------------------------------------------------------------------------------- /test/extend.expect: -------------------------------------------------------------------------------- 1 | value = 20000.100000 2 | -------------------------------------------------------------------------------- /test/method.expect: -------------------------------------------------------------------------------- 1 | value = 1000.200000 2 | -------------------------------------------------------------------------------- /test/array.expect: -------------------------------------------------------------------------------- 1 | value = 100 2 | value = 1 3 | -------------------------------------------------------------------------------- /test/polymorphism.expect: -------------------------------------------------------------------------------- 1 | value = 20300.000000 2 | -------------------------------------------------------------------------------- /test/heap.expect: -------------------------------------------------------------------------------- 1 | value = 100.100000 2 | value = 1000 3 | -------------------------------------------------------------------------------- /test/args.expect: -------------------------------------------------------------------------------- 1 | value = 100 2 | value = 1100 3 | value = 1 4 | -------------------------------------------------------------------------------- /test/structfunc.expect: -------------------------------------------------------------------------------- 1 | value = 100 2 | value = 1000.100000 3 | -------------------------------------------------------------------------------- /test/structvar.expect: -------------------------------------------------------------------------------- 1 | value = 101 2 | value = 10000.100000 3 | -------------------------------------------------------------------------------- /script/mugichac: -------------------------------------------------------------------------------- 1 | ./mugicha_exec c < $1 > tmp.bc && lli tmp.bc 2 | -------------------------------------------------------------------------------- /src/ast.h.gch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TokyoYoshida/MugiCha/HEAD/src/ast.h.gch -------------------------------------------------------------------------------- /src/func.h.gch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TokyoYoshida/MugiCha/HEAD/src/func.h.gch -------------------------------------------------------------------------------- /src/symbol.h.gch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TokyoYoshida/MugiCha/HEAD/src/symbol.h.gch -------------------------------------------------------------------------------- /src/type.h.gch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TokyoYoshida/MugiCha/HEAD/src/type.h.gch -------------------------------------------------------------------------------- /test/method_args.expect: -------------------------------------------------------------------------------- 1 | value = 20000.000000 2 | value = 100.000000 3 | value = 1000 4 | -------------------------------------------------------------------------------- /src/mugicha.h.gch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TokyoYoshida/MugiCha/HEAD/src/mugicha.h.gch -------------------------------------------------------------------------------- /src/support.h.gch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TokyoYoshida/MugiCha/HEAD/src/support.h.gch -------------------------------------------------------------------------------- /test/return_types.expect: -------------------------------------------------------------------------------- 1 | value = 100 2 | value = 1 3 | value = 1.100000 4 | value = test 5 | -------------------------------------------------------------------------------- /test/types.expect: -------------------------------------------------------------------------------- 1 | value = 2 2 | value = 100.100000 3 | value = this is test 4 | value = 1 5 | -------------------------------------------------------------------------------- /test/array.mugi: -------------------------------------------------------------------------------- 1 | func main() int { 2 | var y [int](100) 3 | y[0] = 1 4 | y[1] = 100 5 | print(y[1]) 6 | print(y[0]) 7 | 0 8 | } 9 | -------------------------------------------------------------------------------- /src/callstack.h: -------------------------------------------------------------------------------- 1 | #ifndef CALLSTACK_H 2 | #define CALLSTACK_H 1 3 | 4 | #include "func.h" 5 | 6 | #define CALL_STACK_MAX 100 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /newsample.mugi: -------------------------------------------------------------------------------- 1 | 2 | func main() int { 3 | class Testx { 4 | var x int 5 | } 6 | var y Testx 7 | y = 100 8 | print("ok") 9 | 0 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | y.tab.c 2 | *.bc 3 | *.ll 4 | y.tab.h 5 | lex.yy.c 6 | ast.yy.c 7 | *.o 8 | *.d 9 | mugicha 10 | mugicha_exec 11 | my_support 12 | .tags* 13 | tmp 14 | *.result 15 | *.diff 16 | -------------------------------------------------------------------------------- /test/if.mugi: -------------------------------------------------------------------------------- 1 | func myfunc(var x int) int { 2 | if x > 1000 { 3 | print("good") 4 | } else { 5 | print("ok") 6 | } 7 | } 8 | 9 | func main() int { 10 | myfunc(100) 11 | 0 12 | } 13 | -------------------------------------------------------------------------------- /test/func.mugi: -------------------------------------------------------------------------------- 1 | func test(var x int) int { 2 | while x < 100 { 3 | print(x) 4 | x = x + 1 5 | } 6 | x 7 | } 8 | 9 | func main() int { 10 | var x int 11 | x = test(0) + 1 12 | print(x) 13 | 0 14 | } 15 | -------------------------------------------------------------------------------- /sample.mugi: -------------------------------------------------------------------------------- 1 | class TestX { 2 | var x double 3 | var y int 4 | } 5 | 6 | func main() int { 7 | var a TestX 8 | a = new TestX() 9 | a.x = 100.1 10 | a.y = 1000 11 | print(a.x) 12 | print(a.y) 13 | 0 14 | } 15 | -------------------------------------------------------------------------------- /test/heap.mugi: -------------------------------------------------------------------------------- 1 | class TestX { 2 | var x double 3 | var y int 4 | } 5 | 6 | func main() int { 7 | var a TestX 8 | a = new TestX() 9 | a.x = 100.1 10 | a.y = 1000 11 | print(a.x) 12 | print(a.y) 13 | 0 14 | } 15 | -------------------------------------------------------------------------------- /args.mugi: -------------------------------------------------------------------------------- 1 | func test(var x int , var y int) int { 2 | print(x) 3 | print(y) 4 | x 5 | } 6 | 7 | func main() int { 8 | var x int 9 | var y int 10 | x = 1 11 | y = 100 12 | test(100, 1000 + y) 13 | print(x) 14 | 0 15 | } 16 | -------------------------------------------------------------------------------- /test/args.mugi: -------------------------------------------------------------------------------- 1 | func test(var x int , var y int) int { 2 | print(x) 3 | print(y) 4 | x 5 | } 6 | 7 | func main() int { 8 | var x int 9 | var y int 10 | x = 1 11 | y = 100 12 | test(100, 1000 + y) 13 | print(x) 14 | 0 15 | } 16 | -------------------------------------------------------------------------------- /test/recursive.mugi: -------------------------------------------------------------------------------- 1 | func factorial(var x int) int { 2 | var ret int 3 | if x == 1 { 4 | ret = 1 5 | } else { 6 | ret = x * factorial(x - 1) 7 | } 8 | ret 9 | } 10 | 11 | func main() int { 12 | print(factorial(5)) 13 | 0 14 | } 15 | -------------------------------------------------------------------------------- /test/structfunc.mugi: -------------------------------------------------------------------------------- 1 | class TestX { 2 | var x int 3 | var y double 4 | } 5 | 6 | func test(var a TestX) int { 7 | print(a.x) 8 | print(a.y) 9 | 0 10 | } 11 | 12 | func main() int { 13 | var y TestX 14 | y.x = 100 15 | y.y = 1000.1 16 | test(y) 17 | 0 18 | } 19 | -------------------------------------------------------------------------------- /test/method.mugi: -------------------------------------------------------------------------------- 1 | class TestX { 2 | var x int 3 | var y double 4 | } 5 | 6 | func TestX.test(var a int) int { 7 | this.y = this.y + 0.1 8 | 0 9 | } 10 | 11 | func main() int { 12 | var y TestX 13 | y.x = 100 14 | y.y = 1000.1 15 | y.test(100) 16 | print(y.y) 17 | 0 18 | } 19 | -------------------------------------------------------------------------------- /ok_ver__sample.mugi: -------------------------------------------------------------------------------- 1 | class TestX { 2 | var x int 3 | var y double 4 | } 5 | 6 | func test(var a TestX) int { 7 | 0 8 | } 9 | 10 | func main() int { 11 | var y TestX 12 | var z TestX 13 | y.x = 100 14 | y.y = 10000.1 15 | z = y 16 | print(y.x) 17 | print(z.y) 18 | 0 19 | } 20 | -------------------------------------------------------------------------------- /src/mugicha.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "mugicha.h" 4 | #include "stack.h" 5 | #include "support.h" 6 | 7 | 8 | void display_ast(ASTNODE *rootp) 9 | { 10 | printf("\n------\nAST is \n"); 11 | print_ast(0, rootp); 12 | printf("------\nstart interpret .. \n"); 13 | } 14 | -------------------------------------------------------------------------------- /test/method_args.mugi: -------------------------------------------------------------------------------- 1 | class SuperX { 2 | var z double 3 | } 4 | 5 | func SuperX.test(var a double, var b int) int { 6 | print(this.z) 7 | print(a) 8 | print(b) 9 | 0 10 | } 11 | 12 | func main() int { 13 | var y SuperX 14 | 15 | y.z = 20000.0 16 | y.test(100.0, 1000) 17 | 18 | 0 19 | } 20 | -------------------------------------------------------------------------------- /test/structvar.mugi: -------------------------------------------------------------------------------- 1 | class TestX { 2 | var x int 3 | var y double 4 | } 5 | 6 | func test(var a TestX) int { 7 | 0 8 | } 9 | 10 | func main() int { 11 | var y TestX 12 | var z TestX 13 | y.x = 100 14 | y.y = 10000.1 15 | z = y 16 | z.x = 101 17 | print(y.x) 18 | print(z.y) 19 | 0 20 | } 21 | -------------------------------------------------------------------------------- /src/stack.h: -------------------------------------------------------------------------------- 1 | #define STACK_MAX 100 2 | 3 | typedef struct _stack { 4 | void *ar[STACK_MAX]; 5 | int pos; 6 | } STACK; 7 | 8 | void stack_init(STACK *sp); 9 | void stack_push(STACK *sp, void *p); 10 | void *stack_pop(STACK *sp); 11 | int stack_is_empty(STACK *sp); 12 | 13 | void set_stack_pos(int newpos); 14 | int get_stack_pos(); 15 | -------------------------------------------------------------------------------- /test/return_types.mugi: -------------------------------------------------------------------------------- 1 | func retint() int { 2 | 100 3 | } 4 | 5 | func retbool() bool { 6 | true 7 | } 8 | 9 | func retdouble() double { 10 | 1.1 11 | } 12 | 13 | func retstring() string { 14 | "test" 15 | } 16 | 17 | 18 | func main() int { 19 | print(retint()) 20 | print(retbool()) 21 | print(retdouble()) 22 | print(retstring()) 23 | 0 24 | } 25 | -------------------------------------------------------------------------------- /test/extend.mugi: -------------------------------------------------------------------------------- 1 | class SuperX { 2 | var z double 3 | } 4 | 5 | class TestX : SuperX { 6 | var x int 7 | var y double 8 | } 9 | 10 | func TestX.test(var a int) int { 11 | this.z = this.z + 0.1 12 | 0 13 | } 14 | 15 | func main() int { 16 | var y TestX 17 | y.x = 100 18 | y.y = 1000.1 19 | y.z = 20000.0 20 | y.test(1) 21 | print(y.z) 22 | 0 23 | } 24 | -------------------------------------------------------------------------------- /src/mugicha.h: -------------------------------------------------------------------------------- 1 | #ifndef mugicha_H 2 | #define mugicha_H 1 3 | 4 | #include "ast.h" 5 | #include "dynode.h" 6 | 7 | enum MugichaMode {Interpreter, Compiler, DisplayAst}; 8 | 9 | #define YACC_DEBUG 1 10 | 11 | void interpreter_main(ASTNODE *rootp); 12 | void mugicha_main(ASTNODE *rootp); 13 | void cleanup_astnodes(ASTNODE *np); 14 | void display_ast(ASTNODE *rootp); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /test/types.mugi: -------------------------------------------------------------------------------- 1 | func intfunc(var x int) int { 2 | print(x) 3 | 0 4 | } 5 | 6 | func doublefunc(var x double) int { 7 | print(x) 8 | 0 9 | } 10 | 11 | func strfunc(var x string) int { 12 | print(x) 13 | 0 14 | } 15 | 16 | func boolfunc(var x bool) int { 17 | print(x) 18 | 0 19 | } 20 | 21 | func main() int { 22 | intfunc(2) 23 | doublefunc(100.1) 24 | strfunc("this is test") 25 | boolfunc(true) 26 | 0 27 | } 28 | -------------------------------------------------------------------------------- /src/symbol.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMBOL_H 2 | #define SYMBOL_H 1 3 | 4 | #define SYMBOL_MAX 100 5 | 6 | typedef struct _SYMBOL { 7 | char *name; 8 | } SYMBOL; 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif /* __cplusplus */ 13 | 14 | SYMBOL *lookup_make_symbol(char const *name); 15 | SYMBOL *make_symbol( char const *name); 16 | SYMBOL *lookup_symbol(char const *name); 17 | char *symbol_description(SYMBOL *s); 18 | void print_symbols(); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif /* __cplusplus */ 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /old_sample.mugi: -------------------------------------------------------------------------------- 1 | class SuperX { 2 | var z double 3 | } 4 | 5 | class TestX : SuperX { 6 | var x int 7 | var y double 8 | } 9 | 10 | func SuperX.test(var a double) int { 11 | this.z = this.z + a * 2.0 12 | print(this.z) 13 | 0 14 | } 15 | 16 | func TestX.test(var a double) int { 17 | this.z = this.z + a * 3.0 18 | print(this.z) 19 | 20 | 0 21 | } 22 | 23 | func testfunc(var k SuperX) int { 24 | k.test(a = 100.0) 25 | 0 26 | } 27 | 28 | func main() int { 29 | var y TestX 30 | 31 | y.x = 100 32 | y.y = 1000.1 33 | y.z = 20000.0 34 | 35 | testfunc(k = y) 36 | 0 37 | } 38 | -------------------------------------------------------------------------------- /test/polymorphism.mugi: -------------------------------------------------------------------------------- 1 | class SuperX { 2 | var z double 3 | } 4 | 5 | class TestX : SuperX { 6 | var x int 7 | var y double 8 | } 9 | 10 | func SuperX.test(var a double) int { 11 | this.z = this.z + a * 2.0 12 | print(this.z) 13 | 0 14 | } 15 | 16 | func TestX.test(var a double) int { 17 | this.z = this.z + a * 3.0 18 | print(this.z) 19 | 20 | 0 21 | } 22 | 23 | func testfunc(var k SuperX) int { 24 | k.test(100.0) 25 | 0 26 | } 27 | 28 | func main() int { 29 | var y TestX 30 | 31 | y.x = 100 32 | y.y = 1000.1 33 | y.z = 20000.0 34 | 35 | testfunc(y) 36 | 0 37 | } 38 | -------------------------------------------------------------------------------- /src/dynode.h: -------------------------------------------------------------------------------- 1 | #ifndef DYNODE_H 2 | #define DYNODE_H 1 3 | 4 | #include "ast.h" 5 | 6 | typedef struct _DYNODE { 7 | TYPE type; 8 | OPERATION op; 9 | void *val; 10 | BOOL evaled; 11 | SYMBOL *sym; 12 | struct _ASTNODE *ast; 13 | struct _DYNODE *left; 14 | struct _DYNODE *right; 15 | struct _DYNODE *def_args; 16 | struct _DYNODE *set_args; 17 | } DYNODE; 18 | 19 | void print_dynode(int depth, DYNODE *np); 20 | DYNODE *make_dynode(ASTNODE *ast); 21 | void cleanup_dynode(DYNODE *p); 22 | void make_dynode_sub(DYNODE *dp); 23 | void print_dynodetree(int depth, DYNODE *np); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/stack.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | #include "support.h" 5 | 6 | static STACK *stackp; 7 | 8 | void stack_init(STACK *sp) 9 | { 10 | sp->pos = 0; 11 | stackp = sp; 12 | } 13 | 14 | void stack_push(STACK *sp, void *p) 15 | { 16 | if(sp->pos == STACK_MAX) 17 | ASSERT_FAIL("assertion failed: stack overflow."); 18 | 19 | sp->ar[sp->pos++] = p; 20 | } 21 | 22 | void *stack_pop(STACK *sp) 23 | { 24 | if(sp->pos == 0 ) 25 | ASSERT_FAIL("assertion failed: stack can't pop beacuse of below zero."); 26 | 27 | return sp->ar[--sp->pos]; 28 | } 29 | 30 | int stack_is_empty(STACK *sp) 31 | { 32 | return sp->pos == 0; 33 | } 34 | 35 | void set_stack_pos(int newpos) 36 | { 37 | stackp->pos = newpos; 38 | } 39 | 40 | int get_stack_pos() 41 | { 42 | return stackp->pos; 43 | } 44 | -------------------------------------------------------------------------------- /src/func.h: -------------------------------------------------------------------------------- 1 | #ifndef FUNC_H 2 | #define FUNC_H 1 3 | 4 | #include "support.h" 5 | #include "symbol.h" 6 | #include "type.h" 7 | #include "dynode.h" 8 | 9 | #define FUNC_MAX 100 10 | 11 | typedef struct _FUNC { 12 | SYMBOL *sym; 13 | TYPE reciever_type; 14 | ASTNODE *def; 15 | ASTNODE *body; 16 | TYPE type; 17 | ASTNODE *def_args; 18 | } FUNC; 19 | 20 | typedef struct _FUNCRESULT { 21 | void *retvalue; 22 | } FUNCRESULT; 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif /* __cplusplus */ 27 | 28 | void set_func_pos(int newpos); 29 | int get_func_pos(); 30 | FUNC *lookup_func(SYMBOL *s); 31 | FUNC *make_func(SYMBOL *s, TYPE type, ASTNODE *def, ASTNODE *body, ASTNODE *def_args); 32 | FUNC *make_method(TYPE reciever_type, SYMBOL *s, TYPE type, ASTNODE *def, ASTNODE *body, ASTNODE *def_args); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif /* __cplusplus */ 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## Mugi Cha 2 | 3 | Mugi Cha is Programing Language.
4 | This language has been inspired by the GO language and Scala. 5 | 6 | ## Sample Code 7 | 8 | This is mugicha language sample code. 9 | ``` 10 | func test(var x int) int { 11 | while x < 100 { 12 | print(x) 13 | x = x + 1 14 | } 15 | x 16 | } 17 | 18 | func main() int { 19 | var x int 20 | x = test(x = 0) + 1 21 | print(x) 22 | 0 23 | } 24 | ``` 25 | 26 | ## Build 27 | 28 | To build, run the following command. 29 | ``` 30 | make 31 | ``` 32 | 33 | ## Execution exsample 34 | 35 | run the following command. 36 | 37 | ### for compiler 38 | ``` 39 | make run_compiler 40 | ``` 41 | 42 | ### for interpreter(deprecated) 43 | ``` 44 | make run_interpreter 45 | ``` 46 | 47 | ## contribution 48 | 49 | Contributions welcome! 50 | 51 | If there is contact, please write to the Issues. Or, please mail. 52 | yoshidaforpublic@gmail.com 53 | 54 | ## License 55 | 56 | MIT 57 | -------------------------------------------------------------------------------- /src/symbol.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "symbol.h" 3 | #include "support.h" 4 | 5 | static SYMBOL syms[SYMBOL_MAX]; 6 | static int pos = 0; 7 | 8 | SYMBOL *lookup_make_symbol(char const *name) 9 | { 10 | SYMBOL *s; 11 | s = lookup_symbol(name); 12 | if(s) return s; 13 | 14 | return make_symbol(name); 15 | } 16 | 17 | 18 | SYMBOL *make_symbol(char const *name) 19 | { 20 | if(pos == SYMBOL_MAX) ASSERT_FAIL("out of bounds."); 21 | 22 | syms[pos].name = strdup(name); 23 | 24 | return &syms[pos++]; 25 | } 26 | 27 | SYMBOL *lookup_symbol(char const *name) 28 | { 29 | int i; 30 | SYMBOL *s; 31 | 32 | 33 | for( i = 0 ; i < pos ; i++ ){ 34 | if( !strcmp(syms[i].name, name)) return &syms[i]; 35 | } 36 | 37 | return NULL; 38 | } 39 | 40 | char *symbol_description(SYMBOL *s) 41 | { 42 | static char ret[100]; 43 | sprintf(ret, " symbol name = %s" ,s->name); 44 | 45 | return ret; 46 | } 47 | 48 | void print_symbols() 49 | { 50 | SYMBOL *s; 51 | int i; 52 | 53 | for(i = 0 ; i < pos ; i++){ 54 | s = &syms[i]; 55 | printf("symbol num = %d ,%s\n", i, symbol_description(s)); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/func.c: -------------------------------------------------------------------------------- 1 | #include "func.h" 2 | 3 | static FUNC funcs[FUNC_MAX]; 4 | static int pos; 5 | 6 | void set_func_pos(int newpos) 7 | { 8 | pos = newpos; 9 | } 10 | 11 | int get_func_pos() 12 | { 13 | return pos; 14 | } 15 | 16 | 17 | FUNC *lookup_func(SYMBOL *s) 18 | { 19 | int i; 20 | 21 | for(i = pos-1 ; i >= 0 ; i--){ 22 | if( funcs[i].sym == s ) return &funcs[i]; 23 | } 24 | 25 | return NULL; 26 | } 27 | 28 | FUNC *make_func(SYMBOL *s, TYPE type, ASTNODE *def, ASTNODE *body, ASTNODE *def_args) 29 | { 30 | if( pos == FUNC_MAX) ASSERT_FAIL("out of bounds."); 31 | 32 | funcs[pos].sym = s; 33 | funcs[pos].type = type; 34 | funcs[pos].def = def; 35 | funcs[pos].body = body; 36 | funcs[pos].def_args = def_args; 37 | 38 | return &funcs[pos++]; 39 | } 40 | 41 | FUNC *make_method(TYPE reciever_type, SYMBOL *s, TYPE type, ASTNODE *def, ASTNODE *body, ASTNODE *def_args) 42 | { 43 | if( pos == FUNC_MAX) ASSERT_FAIL("out of bounds."); 44 | 45 | funcs[pos].reciever_type = reciever_type; 46 | funcs[pos].sym = s; 47 | funcs[pos].type = type; 48 | funcs[pos].def = def; 49 | funcs[pos].body = body; 50 | funcs[pos].def_args = def_args; 51 | 52 | return &funcs[pos++]; 53 | } 54 | -------------------------------------------------------------------------------- /src/type.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPE_H 2 | #define TYPE_H 1 3 | 4 | #include "symbol.h" 5 | 6 | typedef enum _BOOL {FALSE, TRUE} BOOL; 7 | 8 | typedef enum _TYPEKIND {ANY, INT, DOUBLE, BOOLTYPE, STRING, ARRAY, KLASS} TYPEKIND; 9 | 10 | typedef struct _TYPE { 11 | TYPEKIND kind; 12 | TYPEKIND elem_kind; 13 | SYMBOL *klass; 14 | } TYPE; 15 | 16 | typedef enum _OPERATION {NONE, VALUEDATA, ADD, SUB, MUL, DIV, SEQ, EXPR_LIST, DEF_ARGS, PRINTDATA, DEF_VAR, SET_VAR, GET_VAR, DEF_FUNC, DEF_METHOD, CALL_FUNC, CALL_METHOD, CMP_EQ, CMP_NOTEQ,CMP_GREATER, CMP_SMALLER, CMP_GREATEREQ, CMP_SMALLEREQ ,IF_STMT,WHILE_STMT ,SET_MEMBER_VAR, SET_ARRAY_VAR, GET_MEMBER_VAR, GET_ARRAY_VAR, NEW_CLASS, DEF_CLASS } OPERATION ; // if modify this place, you also must modify function `get_op_description`. 17 | 18 | union _v { 19 | char *s; 20 | void *v; 21 | int i; 22 | double d; 23 | BOOL b; 24 | }; 25 | 26 | typedef struct _VALUE { 27 | TYPE type; 28 | union _v val; 29 | } VALUE; 30 | 31 | #define STRING_LENGTH_MAX 255 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif /* __cplusplus */ 36 | 37 | char *value_description(VALUE val); 38 | char *get_type_description(TYPEKIND i); 39 | char *get_op_description(OPERATION i); 40 | TYPEKIND get_type_by_name(char *name); 41 | char *get_bool_description(BOOL val); 42 | int comp_val(VALUE lhr, VALUE rhr); 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif /* __cplusplus */ 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /test/func.expect: -------------------------------------------------------------------------------- 1 | value = 0 2 | value = 1 3 | value = 2 4 | value = 3 5 | value = 4 6 | value = 5 7 | value = 6 8 | value = 7 9 | value = 8 10 | value = 9 11 | value = 10 12 | value = 11 13 | value = 12 14 | value = 13 15 | value = 14 16 | value = 15 17 | value = 16 18 | value = 17 19 | value = 18 20 | value = 19 21 | value = 20 22 | value = 21 23 | value = 22 24 | value = 23 25 | value = 24 26 | value = 25 27 | value = 26 28 | value = 27 29 | value = 28 30 | value = 29 31 | value = 30 32 | value = 31 33 | value = 32 34 | value = 33 35 | value = 34 36 | value = 35 37 | value = 36 38 | value = 37 39 | value = 38 40 | value = 39 41 | value = 40 42 | value = 41 43 | value = 42 44 | value = 43 45 | value = 44 46 | value = 45 47 | value = 46 48 | value = 47 49 | value = 48 50 | value = 49 51 | value = 50 52 | value = 51 53 | value = 52 54 | value = 53 55 | value = 54 56 | value = 55 57 | value = 56 58 | value = 57 59 | value = 58 60 | value = 59 61 | value = 60 62 | value = 61 63 | value = 62 64 | value = 63 65 | value = 64 66 | value = 65 67 | value = 66 68 | value = 67 69 | value = 68 70 | value = 69 71 | value = 70 72 | value = 71 73 | value = 72 74 | value = 73 75 | value = 74 76 | value = 75 77 | value = 76 78 | value = 77 79 | value = 78 80 | value = 79 81 | value = 80 82 | value = 81 83 | value = 82 84 | value = 83 85 | value = 84 86 | value = 85 87 | value = 86 88 | value = 87 89 | value = 88 90 | value = 89 91 | value = 90 92 | value = 91 93 | value = 92 94 | value = 93 95 | value = 94 96 | value = 95 97 | value = 96 98 | value = 97 99 | value = 98 100 | value = 99 101 | value = 101 102 | -------------------------------------------------------------------------------- /src/support.h: -------------------------------------------------------------------------------- 1 | #ifndef SUPPORT_H 2 | #define SUPPORT_H 1 3 | 4 | #include 5 | #include 6 | 7 | #define MUGICHA_DEBUG 1 8 | 9 | #ifdef MUGICHA_DEBUG 10 | 11 | #define DEBUGL fprintf(stderr, "%s:%d\n",__FILE__,__LINE__) 12 | #define DEBUGP(p) fprintf(stderr, "%s:%d addr = %p\n",__FILE__, __LINE__, p) 13 | #define DEBUGS(m) fprintf(stderr, "%s:%d message = %s\n",__FILE__, __LINE__, m) 14 | #define DEBUGI(i) fprintf(stderr, "%s:%d int data = %d\n",__FILE__, __LINE__, i) 15 | #define DEBUGW(m) fprintf(stderr, "%s:%d label = %s",__FILE__, __LINE__, m) 16 | 17 | // Use for temporary work only 18 | #define TMP_DEBUGL fprintf(stderr, "%s:%d\n",__FILE__,__LINE__) 19 | #define TMP_DEBUGP(p) fprintf(stderr, "%s:%d addr = %p\n",__FILE__, __LINE__, p) 20 | #define TMP_DEBUGS(m) fprintf(stderr, "%s:%d message = %s\n",__FILE__, __LINE__, m) 21 | #define TMP_DEBUGI(i) fprintf(stderr, "%s:%d int data = %d\n",__FILE__, __LINE__, i) 22 | #define TMP_DEBUGW(m) fprintf(stderr, "%s:%d label = %s",__FILE__, __LINE__, m) 23 | 24 | #else 25 | 26 | #define DEBUGL ((void)0) 27 | #define DEBUGP(p) ((void)0) 28 | #define DEBUGS(m) ((void)0) 29 | #define DEBUGI(i) ((void)0) 30 | #define DEBUGW(m) ((void)0) 31 | 32 | #define TMP_DEBUGL ((void)0) 33 | #define TMP_DEBUGP(p) ((void)0) 34 | #define TMP_DEBUGS(m) ((void)0) 35 | #define TMP_DEBUGI(i) ((void)0) 36 | #define TMP_DEBUGW(m) ((void)0) 37 | 38 | #endif 39 | 40 | #define ASSERT_FAIL(s) fprintf(stderr, "%s:%d assertion fail (%s)\n",__FILE__, __LINE__, s), exit(1) 41 | #define ASSERT_FAIL_BLOCK() fprintf(stderr, "%s:%d assertion fail (this block expect never call.)\n",__FILE__, __LINE__), exit(1) 42 | #define ASSERT_FAIL_MEMORY() fprintf(stderr, "%s:%d assertion fail (memory error.)\n",__FILE__, __LINE__), exit(1) 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .SUFFIXES: 2 | 3 | PROG = mugicha_exec 4 | LEXS = $(wildcard src/*.l) 5 | YACCS = $(wildcard src/*.y) 6 | LEXC = src/lex.yy.c 7 | YACCC = src/y.tab.c 8 | YACCH = src/y.tab.h 9 | LEXO = src/lex.yy.o 10 | YACCO = src/y.tab.o 11 | CSRCS = $(wildcard src/*.c) 12 | CPPSRCS = $(wildcard src/*.cpp) 13 | OBJS = $(CSRCS:%.c=%.o) $(CPPSRCS:%.cpp=%.o) $(LEXO) $(YACCO) 14 | DEPS = $(CSRCS:%.c=%.d) $(CPPSRCS:%.cpp=%.d) 15 | MUGICHAC = script/mugichac 16 | TESTS = $(wildcard test/*.mugi) 17 | RESULTS = $(TESTS:%.mugi=%.result) 18 | EXPECTS = $(TESTS:%.mugi=%.expect) 19 | DIFFS = $(TESTS:%.mugi=%.diff) 20 | 21 | CC = clang 22 | CPP = clang++ 23 | CPPFLG = -g -O3 -std=c++11 -fno-exceptions $1 `llvm-config --cppflags` 24 | LDFLG = -ll -ly -g -O3 -std=c++11 -fno-exceptions $1 `llvm-config --ldflags --system-libs --libs core executionengine interpreter mc support nativecodegen` 25 | LEX = lex 26 | YACC = yacc 27 | 28 | all: $(PROG) 29 | 30 | -include $(DEPS) 31 | 32 | $(PROG): $(OBJS) 33 | $(CPP) $(LDFLG) -o $(PROG) $^ 34 | 35 | $(YACCC): $(YACCS) 36 | $(YACC) $< -o $(YACCC) -d -t 37 | 38 | $(LEXC): $(LEXS) 39 | $(LEX) -t $< > $(LEXC) 40 | 41 | %.o: %.c $(YACCC) $(LEXC) 42 | $(CC) -c -MMD -MP -o $@ $< 43 | 44 | %.o: %.cpp 45 | $(CPP) -c $(CPPFLG) -o $@ $< 46 | 47 | clean: 48 | rm -f $(PROG) $(OBJS) $(DEPS) $(YACCO) $(LEXO) $(YACCC) $(LEXC) $(YACCH) $(RESULTS) $(DIFFS) 49 | 50 | clean_test_results: 51 | rm -f $(RESULTS) $(DIFFS) 52 | 53 | disp_ast: 54 | ./mugicha_exec a < sample.mugi 55 | 56 | run_interpreter: 57 | ./mugicha_exec i < sample.mugi 58 | 59 | run_compiler: 60 | $(MUGICHAC) sample.mugi 61 | 62 | test: $(DIFFS) 63 | echo "The test is successful." 64 | 65 | %.diff: %.result %.expect 66 | diff $(basename $<).result $(basename $<).expect > $@ 67 | 68 | %.result: %.mugi 69 | $(MUGICHAC) $< > $@ 70 | 71 | $(TESTS): $(PROG) 72 | touch $@ 73 | -------------------------------------------------------------------------------- /src/type.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "type.h" 4 | #include "support.h" 5 | 6 | 7 | char *value_description(VALUE val) 8 | { 9 | static char ret[STRING_LENGTH_MAX]; 10 | 11 | switch(val.type.kind){ 12 | case INT: 13 | sprintf(ret, "%d" ,val.val.i); 14 | break; 15 | case DOUBLE: 16 | sprintf(ret, "%f" , val.val.d); 17 | break; 18 | case BOOLTYPE: 19 | sprintf(ret, "%s" , get_bool_description(val.val.b)); 20 | break; 21 | case STRING: 22 | sprintf(ret, "%s" ,val.val.s); 23 | break; 24 | case ANY: 25 | return "ANY"; 26 | } 27 | 28 | return ret; 29 | } 30 | 31 | char *get_type_description(TYPEKIND i) 32 | { 33 | static char *type_a[] = {"ANY", "INT", "DOUBLE","BOOLTYPE","STRING","ARRAY", "KLASS"}; 34 | 35 | if(i > KLASS ) ASSERT_FAIL("out of bounds"); 36 | 37 | return type_a[i]; 38 | } 39 | 40 | char *get_op_description(OPERATION i) 41 | { 42 | static char *op_a[] = {"NONE", "VALUEDATA", "ADD", "SUB", "MUL", "DIV", "SEQ", 43 | "EXPR_LIST", "DEF_ARGS", "PRINTDATA", "DEF_VAR", "SET_VAR", "GET_VAR", "DEF_FUNC", "DEF_METHOD", "CALL_FUNC", "CALL_METHOD","CMP_EQ", "CMP_NOTEQ", "CMP_GREATER", "CMP_SMALLE", "CMP_GREATEREQ", "CMP_SMALLEEQ", "IF_STMT","WHILE_STMT", "SET_MEMBER_VAR", "SET_ARRAY_VAR", "GET_MEMBER_VAR", "GET_ARRAY_VAR", "NEW_CLASS", "DEF_CLASS"}; // if modify this place, you also must modify type `_OPERATION`. 44 | 45 | if(i > DEF_CLASS) ASSERT_FAIL("out of bounds"); 46 | 47 | return op_a[i]; 48 | } 49 | 50 | TYPEKIND get_type_by_name(char *name) 51 | { 52 | if(!strcmp(name,"int")){ 53 | return INT; 54 | } else if (!strcmp(name,"double")){ 55 | return DOUBLE; 56 | } else if (!strcmp(name,"bool")){ 57 | return BOOLTYPE; 58 | } else if (!strcmp(name,"string")){ 59 | return STRING; 60 | } else if (lookup_symbol(name)){ 61 | return KLASS; 62 | } 63 | ASSERT_FAIL("this block expect never call."); 64 | } 65 | 66 | char *get_bool_description(BOOL val) 67 | { 68 | static char *bools[] = {"false","true"}; 69 | return bools[val]; 70 | } 71 | -------------------------------------------------------------------------------- /src/mugicha_compiler.h: -------------------------------------------------------------------------------- 1 | #ifndef LLVM_COMPILER_H 2 | #define LLVM_COMPILER_H 1 3 | 4 | #include "llvm_builder.h" 5 | 6 | #ifndef __cplusplus 7 | 8 | void mugicha_compile(ASTNODE *rootp); 9 | 10 | #endif 11 | 12 | #ifdef __cplusplus 13 | 14 | class MugichaScopeInfo { 15 | std::shared_ptr context_; 16 | std::shared_ptr module_; 17 | std::shared_ptr var_map_; 18 | std::shared_ptr struct_def_map_; 19 | std::shared_ptr klass_def_map_; 20 | std::shared_ptr storage_; 21 | llvm::GlobalVariable *func_ptr_arr_; 22 | // if you add a field ,you must also add copy constructor. 23 | 24 | public: 25 | 26 | MugichaScopeInfo(); 27 | 28 | MugichaScopeInfo(std::shared_ptr old_scope) ; 29 | 30 | std::shared_ptr getModuleBuilder(); 31 | 32 | llvm::Module *getModule(); 33 | 34 | llvm::LLVMContext *getContext(); 35 | 36 | llvm::IRBuilder<> *getBuilder(); 37 | 38 | llvm::Function *getFunc(); 39 | 40 | std::shared_ptr getFuncBuilder(); 41 | 42 | std::shared_ptr makeExprBuilder(); 43 | 44 | std::shared_ptr getVarMap(); 45 | 46 | std::shared_ptr getStructDefMap(); 47 | 48 | std::shared_ptr getKlassDefMap(); 49 | 50 | std::shared_ptr getStorage(); 51 | 52 | int getKlassMax(); 53 | 54 | int getMethodMax(); 55 | 56 | int getMethodArrayIndex(int klass_id, int method_id); 57 | 58 | llvm::Value *getMethodFromArray(int klass_id, int method_id); 59 | 60 | void setFuncPtrArry(); 61 | 62 | void makeFuncPtrArry(); 63 | 64 | llvm::GlobalVariable *getFuncPtrArry(); 65 | 66 | private: 67 | llvm::PointerType *getOpequePtrType(); 68 | 69 | llvm::ArrayType *getFuncArrayType(); 70 | 71 | }; 72 | 73 | llvm::Type *getLLVMTypeByMugichaType(TYPE type,llvm::LLVMContext *context); 74 | 75 | llvm::Value *eval_node_codegen(ASTNODE *ap, std::shared_ptr scope); 76 | LLVMStructDef::FieldDef getFieldDef(LLVMModuleBuilder *module, ASTNODE *ap); 77 | 78 | #endif /* __cplusplus */ 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/ast.h: -------------------------------------------------------------------------------- 1 | #ifndef NODE_H 2 | #define NODE_H 1 3 | 4 | #include "type.h" 5 | #include "symbol.h" 6 | 7 | #define VAR_NAME_MAX 20 8 | 9 | typedef struct _ASTNODE { 10 | TYPE type; 11 | OPERATION op; 12 | VALUE val; 13 | SYMBOL *sym; 14 | SYMBOL *member; 15 | SYMBOL *reciever; 16 | SYMBOL *super_class; 17 | TYPE reciever_type; 18 | struct _ASTNODE *left; 19 | struct _ASTNODE *right; 20 | struct _ASTNODE *set_args; 21 | struct _ASTNODE *condition; 22 | struct _ASTNODE *def_vars; 23 | } ASTNODE; 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif /* __cplusplus */ 28 | ASTNODE *make_ast_int(int val); 29 | ASTNODE *make_ast_bool(BOOL val); 30 | ASTNODE *make_ast_double(double val); 31 | ASTNODE *make_ast_string(char *val); 32 | 33 | ASTNODE *make_ast_op(OPERATION op, ASTNODE *lhr, ASTNODE *rhr); 34 | ASTNODE *make_ast_cmd(OPERATION op, ASTNODE *argp); 35 | ASTNODE *make_astnode(); 36 | 37 | ASTNODE *make_ast_op(OPERATION op, ASTNODE *lhr, ASTNODE *rhr); 38 | ASTNODE *make_ast_cmd(OPERATION op, ASTNODE *argp); 39 | ASTNODE *make_ast_def_var(char *name, char *type_name); 40 | ASTNODE *make_ast_def_array(char *name, char *type_name, ASTNODE *size); 41 | ASTNODE *make_ast_set_var(char *name, ASTNODE *rhr); 42 | ASTNODE *make_ast_set_member_var(char *var_name, char *member_name, ASTNODE *newval); 43 | ASTNODE *make_ast_get_member_var(char *var_name, char *member_name); 44 | ASTNODE *make_ast_set_array_var(char *var_name, ASTNODE *index_node, ASTNODE *newval); 45 | ASTNODE *make_ast_get_array_var(char *var_name, ASTNODE *index_node); 46 | ASTNODE *make_ast_get_var(char *name); 47 | ASTNODE *make_ast_def_func(char *name, ASTNODE *def_args, char *type_name, ASTNODE *body); 48 | ASTNODE *make_ast_def_method(char *reciever_name, char *method_name, ASTNODE *def_args, char *type_name, ASTNODE *body); 49 | ASTNODE *make_ast_call_method(char *reviever_name, char *method_name, ASTNODE *set_args); 50 | 51 | ASTNODE *make_ast_def_class(char *name, char *super_name, ASTNODE *def_vars); 52 | ASTNODE *make_ast_new_class(char *name, ASTNODE *set_args); 53 | 54 | ASTNODE *make_ast_call_func(char *name, ASTNODE *set_args); 55 | ASTNODE *make_ast_if(ASTNODE *cond, ASTNODE *then_stmt, ASTNODE *else_stmt); 56 | ASTNODE *make_ast_while(ASTNODE *cond, ASTNODE *loop_stmt); 57 | 58 | ASTNODE *search_ast_by_sym(ASTNODE *ap, char *sym_name); 59 | 60 | void print_astnode(int depth, ASTNODE *np); 61 | void print_astnodeln(int depth, ASTNODE *np); 62 | void print_ast(int depth, ASTNODE *np); 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif /* __cplusplus */ 67 | 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/mugicha.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #include "y.tab.h" 5 | #include "mugicha.h" 6 | #include "support.h" 7 | 8 | int 9 | yywrap(void) 10 | { 11 | return 1; 12 | } 13 | 14 | /* TODO delete later 15 | void print_op(ASTNODE *np){ 16 | if(np->op != VALUEDATA){ 17 | printf("this is not value\n"); 18 | return; 19 | } 20 | 21 | switch(np->type){ 22 | case INT: 23 | printf(">>%d\n", *(int *)np->val); 24 | breakl 25 | case DOUBLE: 26 | printf(">>%f\n", *(double *)np->val); 27 | break; 28 | case ANY: 29 | ASSERT_FAIL("this block expect never call"); 30 | } 31 | 32 | } 33 | */ 34 | 35 | %} 36 | %% 37 | "+" return '+'; 38 | "-" return '-'; 39 | "*" return '*'; 40 | "/" return '/'; 41 | "(" return '('; 42 | ")" return ')'; 43 | "{" return '{'; 44 | "}" return '}'; 45 | "." return '.'; 46 | ":" return ':'; 47 | "=" return '='; 48 | "," return ','; 49 | "==" return EQUAL; 50 | "!=" return NOTEQUAL; 51 | ">" return '>'; 52 | "<" return '<'; 53 | ">=" return GREATEREQUAL; 54 | "<=" return SMALLEREQUAL; 55 | "!" return '!'; 56 | "[" return '['; 57 | "]" return ']'; 58 | "if" return IF; 59 | "else" return ELSE; 60 | "print" return PRINT; 61 | "var" return VAR; 62 | "func" return FUNCTION; 63 | "class" return CLASSDEF; 64 | "while" return WHILE; 65 | "new" return NEW; 66 | \"[^\"]*\" { 67 | char temp[STRING_LENGTH_MAX]; 68 | char *s; 69 | 70 | strncpy(temp, yytext, strlen(yytext)); 71 | 72 | s = malloc(strlen(yytext)); 73 | strncpy(s, (yytext+1), strlen(yytext)-2); 74 | if(!s) ASSERT_FAIL_MEMORY(); 75 | 76 | yylval.np = make_ast_string(s); 77 | 78 | return STRING_LITERAL; 79 | } 80 | [0-9]+\.*[0-9]* { 81 | double temp; 82 | int *np; 83 | ASTNODE *ASTNODEp; 84 | 85 | sscanf(yytext, "%lf", &temp); 86 | 87 | ASTNODEp = yylval.np; 88 | 89 | if(strstr(yytext,".")){ 90 | yylval.np = make_ast_double(temp); 91 | return DOUBLE_LITERAL; 92 | } else { 93 | yylval.np = make_ast_int((int )temp); 94 | return INT_LITERAL; 95 | } 96 | ASSERT_FAIL_BLOCK(); 97 | } 98 | (true|false) { 99 | char temp[7]; 100 | BOOL bool; 101 | sscanf(yytext, "%s", temp); 102 | 103 | if(!strcmp(temp, "true")){ 104 | bool = TRUE; 105 | } else { 106 | bool = FALSE; 107 | } 108 | 109 | yylval.np = make_ast_bool(bool); 110 | 111 | 112 | return BOOL_LITERAL; 113 | } 114 | [a-zA-Z][a-zA-Z0-9]* { 115 | char temp[VAR_NAME_MAX]; 116 | 117 | sscanf(yytext, "%s", temp); 118 | 119 | yylval.str = strdup(temp); 120 | DEBUGS(temp); 121 | 122 | return NAME; 123 | } 124 | %% 125 | -------------------------------------------------------------------------------- /src/mugicha.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #include "mugicha.h" 5 | #include "support.h" 6 | #include "llvm_builder.h" 7 | #define YYDEBUG 1 8 | 9 | static enum MugichaMode mugichaMode; 10 | 11 | #ifdef YACC_DEBUG 12 | int yydebug=1; 13 | #endif 14 | 15 | %} 16 | %union { 17 | struct _ASTNODE *np; 18 | char *str; 19 | } 20 | %token DOUBLE_LITERAL INT_LITERAL BOOL_LITERAL STRING_LITERAL 21 | %token NAME 22 | %token '+' '-' '*' '/' '\n' '(' ')' '.' ':' '=' EQUAL PRINT VAR FUNCTION CLASSDEF NOTEQUAL '!' '<' '>' '\"' '[' ']' ',' 23 | %token SMALLEREQUAL GREATEREQUAL IF ELSE WHILE NEW 24 | %type prog stmt expr expr_print def_var set_var set_member_var 25 | %type def_class new_class def_vars 26 | %type def_func call_func def_method call_method primary_bool expr_cmp_eq expr_cmp_noteq 27 | %type expr_cmp_greater expr_cmp_smaller expr_cmp_greaterequal expr_cmp_smallerequal 28 | %type if_stmt expr_bool while_stmt primary_double primary_string 29 | %type primary_int primary_get_variable primary_get_member_var 30 | %type expr_list def_args expr_int primary_get_array_var set_array_var 31 | %right '=' 32 | %right '!' 33 | %left '+' '-' 34 | %left '*' '/' 35 | %left '.' 36 | %left EQUAL NOTEQUAL '<' '>' SMALLEREQUAL GREATEREQUAL 37 | 38 | %start prog 39 | 40 | %% 41 | prog 42 | : /* empty */ 43 | | stmt 44 | { 45 | if( mugichaMode == Compiler){ 46 | mugicha_compile($1); 47 | } else if( mugichaMode == DisplayAst){ 48 | display_ast($1); 49 | } 50 | } 51 | ; 52 | stmt 53 | : expr 54 | | def_var 55 | | set_var 56 | | set_member_var 57 | | set_array_var 58 | | def_func 59 | | def_method 60 | | def_class 61 | | if_stmt 62 | | while_stmt 63 | | stmt stmt 64 | { 65 | $$ = make_ast_op(SEQ, $1, $2); 66 | } 67 | ; 68 | def_class 69 | : CLASSDEF NAME '{' def_vars '}' 70 | { 71 | $$ = make_ast_def_class($2, NULL, $4); 72 | } 73 | | CLASSDEF NAME '{' '}' 74 | { 75 | $$ = make_ast_def_class($2, NULL, NULL); 76 | } 77 | | CLASSDEF NAME ':' NAME '{' def_vars '}' 78 | { 79 | $$ = make_ast_def_class($2, $4, $6); 80 | } 81 | | CLASSDEF NAME ':' NAME '{' '}' 82 | { 83 | $$ = make_ast_def_class($2, $4, NULL); 84 | } 85 | ; 86 | def_vars 87 | : def_var 88 | | def_vars def_var 89 | { 90 | $$ = make_ast_op(SEQ, $1, $2); 91 | } 92 | ; 93 | def_func 94 | : FUNCTION NAME '(' def_var ')' NAME '{' stmt '}' 95 | { 96 | $$ = make_ast_def_func($2, $4, $6, $8); 97 | } 98 | | FUNCTION NAME '(' def_args ')' NAME '{' stmt '}' 99 | { 100 | $$ = make_ast_def_func($2, $4, $6, $8); 101 | } 102 | | FUNCTION NAME '(' ')' NAME '{' stmt '}' 103 | { 104 | $$ = make_ast_def_func($2, NULL, $5, $7); 105 | } 106 | ; 107 | def_method 108 | : FUNCTION NAME '.' NAME '(' def_var ')' NAME '{' stmt '}' 109 | { 110 | TMP_DEBUGL; 111 | $$ = make_ast_def_method($2, $4, $6, $8, $10); 112 | } 113 | | FUNCTION NAME '.' NAME '(' def_args ')' NAME '{' stmt '}' 114 | { 115 | $$ = make_ast_def_method($2, $4, $6, $8, $10); 116 | } 117 | | FUNCTION NAME '.' NAME '(' ')' NAME '{' stmt '}' 118 | { 119 | TMP_DEBUGL; 120 | $$ = make_ast_def_method($2, $4, NULL, $7, $9); 121 | } 122 | ; 123 | def_args 124 | : def_var ',' def_var 125 | { 126 | $$ = make_ast_op(DEF_ARGS, $1, $3); 127 | } 128 | ; 129 | def_var 130 | : VAR NAME NAME 131 | { 132 | $$ = make_ast_def_var($2, $3); 133 | } 134 | | VAR NAME '[' NAME ']' '(' expr ')' 135 | { 136 | $$ = make_ast_def_array($2, $4, $7); 137 | } 138 | ; 139 | set_var 140 | : NAME '=' expr 141 | { 142 | $$ = make_ast_set_var($1, $3); 143 | } 144 | ; 145 | set_member_var 146 | : NAME '.' NAME '=' expr 147 | { 148 | $$ = make_ast_set_member_var($1, $3, $5); 149 | } 150 | ; 151 | set_array_var 152 | : NAME '[' expr_int ']' '=' expr 153 | { 154 | $$ = make_ast_set_array_var($1, $3, $6); 155 | } 156 | ; 157 | if_stmt 158 | : IF expr_bool '{' stmt '}' ELSE '{' stmt '}' 159 | { 160 | $$ = make_ast_if($2, $4 ,$8); 161 | } 162 | ; 163 | while_stmt 164 | : WHILE expr_bool '{' stmt '}' 165 | { 166 | $$ = make_ast_while($2, $4 ); 167 | } 168 | ; 169 | expr 170 | : primary_int 171 | | expr_print 172 | | expr_bool 173 | | primary_double 174 | | primary_string 175 | | call_func 176 | | call_method 177 | | new_class 178 | | primary_get_variable 179 | | primary_get_member_var 180 | | primary_get_array_var 181 | | expr_int 182 | | expr '+' expr 183 | { 184 | $$ = make_ast_op(ADD, $1, $3); 185 | } 186 | | expr '-' expr 187 | { 188 | $$ = make_ast_op(SUB, $1, $3); 189 | } 190 | | expr '*' expr 191 | { 192 | $$ = make_ast_op(MUL, $1, $3); 193 | } 194 | | expr '/' expr 195 | { 196 | $$ = make_ast_op(DIV, $1, $3); 197 | } 198 | ; 199 | new_class 200 | : NEW NAME '(' expr_list ')' 201 | { 202 | $$ = make_ast_new_class($2, $4); 203 | } 204 | | NEW NAME '(' ')' 205 | { 206 | $$ = make_ast_new_class($2, NULL); 207 | } 208 | ; 209 | call_func 210 | : NAME '(' expr_list ')' 211 | { 212 | $$ = make_ast_call_func($1, $3); 213 | } 214 | | NAME '(' expr ')' 215 | { 216 | $$ = make_ast_call_func($1, $3); 217 | } 218 | | NAME '(' ')' 219 | { 220 | $$ = make_ast_call_func($1, NULL); 221 | } 222 | ; 223 | call_method 224 | : NAME '.' NAME '(' expr_list ')' 225 | { 226 | $$ = make_ast_call_method($1, $3, $5); 227 | } 228 | | NAME '.' NAME '(' expr ')' 229 | { 230 | $$ = make_ast_call_method($1, $3, $5); 231 | } 232 | | NAME '.' NAME '(' ')' 233 | { 234 | $$ = make_ast_call_method($1, NULL, NULL); 235 | } 236 | ; 237 | expr_list 238 | : expr ',' expr 239 | { 240 | $$ = make_ast_op(EXPR_LIST, $1, $3); 241 | } 242 | ; 243 | expr_print 244 | : PRINT '(' stmt ')' 245 | { 246 | $$ = make_ast_cmd(PRINTDATA, $3); 247 | } 248 | | PRINT '(' expr ')' 249 | { 250 | $$ = make_ast_cmd(PRINTDATA, $3); 251 | } 252 | ; 253 | expr_int 254 | : primary_int 255 | | expr_int '+' expr_int 256 | { 257 | $$ = make_ast_op(ADD, $1, $3); 258 | } 259 | | expr_int '-' expr_int 260 | { 261 | $$ = make_ast_op(SUB, $1, $3); 262 | } 263 | | expr_int '*' expr_int 264 | { 265 | $$ = make_ast_op(MUL, $1, $3); 266 | } 267 | | expr_int '/' expr_int 268 | { 269 | $$ = make_ast_op(DIV, $1, $3); 270 | } 271 | ; 272 | expr_bool 273 | : primary_bool 274 | | expr_cmp_eq 275 | | expr_cmp_noteq 276 | | expr_cmp_greater 277 | | expr_cmp_smaller 278 | | expr_cmp_greaterequal 279 | | expr_cmp_smallerequal 280 | ; 281 | expr_cmp_eq 282 | : expr EQUAL expr 283 | { 284 | $$ = make_ast_op(CMP_EQ, $1 ,$3); 285 | } 286 | ; 287 | expr_cmp_noteq 288 | : expr NOTEQUAL expr 289 | { 290 | $$ = make_ast_op(CMP_NOTEQ, $1 ,$3); 291 | } 292 | ; 293 | expr_cmp_greater 294 | : expr '>' expr 295 | { 296 | $$ = make_ast_op(CMP_GREATER, $1 ,$3); 297 | } 298 | ; 299 | expr_cmp_smaller 300 | : expr '<' expr 301 | { 302 | $$ = make_ast_op(CMP_SMALLER, $1 ,$3); 303 | } 304 | ; 305 | expr_cmp_greaterequal 306 | : primary_int GREATEREQUAL primary_int 307 | { 308 | $$ = make_ast_op(CMP_GREATEREQ, $1 ,$3); 309 | } 310 | ; 311 | expr_cmp_smallerequal 312 | : primary_int SMALLEREQUAL primary_int 313 | { 314 | $$ = make_ast_op(CMP_SMALLEREQ, $1 ,$3); 315 | } 316 | ; 317 | primary_int 318 | : INT_LITERAL 319 | ; 320 | primary_double 321 | : DOUBLE_LITERAL 322 | ; 323 | primary_string 324 | : STRING_LITERAL 325 | ; 326 | primary_bool 327 | : BOOL_LITERAL 328 | ; 329 | primary_get_variable 330 | : NAME 331 | { 332 | $$ = make_ast_get_var($1); 333 | } 334 | ; 335 | primary_get_member_var 336 | : NAME '.' NAME 337 | { 338 | $$ = make_ast_get_member_var($1, $3); 339 | } 340 | ; 341 | primary_get_array_var 342 | : NAME '[' expr_int ']' 343 | { 344 | $$ = make_ast_get_array_var($1, $3); 345 | } 346 | ; 347 | %% 348 | 349 | int 350 | yyerror(char const *str) 351 | { 352 | extern char *yytext; 353 | fprintf(stderr, "parser error near %s\n", yytext); 354 | return 0; 355 | } 356 | 357 | int main(int argc,char *argv[]) 358 | { 359 | extern int yyparse(void); 360 | extern FILE *yyin; 361 | 362 | if(argc > 1){ 363 | if(!strcmp(argv[1],"i")){ 364 | mugichaMode = Interpreter; 365 | } else if(!strcmp(argv[1],"c")){ 366 | mugichaMode = Compiler; 367 | } else if(!strcmp(argv[1],"a")){ 368 | mugichaMode = DisplayAst; 369 | } 370 | } 371 | 372 | yyin = stdin; 373 | if (yyparse()) { 374 | fprintf(stderr, "Symtax Error\n"); 375 | exit(1); 376 | } 377 | 378 | return 0; 379 | } 380 | -------------------------------------------------------------------------------- /src/llvm_builder.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LLVM_BUILDER_H 3 | #define LLVM_BUILDER_H 1 4 | 5 | #ifdef __cplusplus 6 | #include "type.h" 7 | 8 | class LLVMModuleBuilder { 9 | protected: 10 | std::shared_ptr module_; 11 | std::shared_ptr context_; 12 | std::shared_ptr> builder_; 13 | 14 | public: 15 | LLVMModuleBuilder(std::string name, std::shared_ptr context); 16 | 17 | llvm::Module *getModule(); 18 | 19 | llvm::LLVMContext *getContext(); 20 | 21 | llvm::IRBuilder<> *getBuilder(); 22 | 23 | llvm::Value *makePrintf(std::vector values); 24 | llvm::Value *makeMalloc(llvm::Constant *AllocSize, llvm::Type *DestTy); 25 | llvm::AllocaInst *makeMallocForType(llvm::Type *DestTy); 26 | }; 27 | 28 | 29 | class LLVMFuncBuilder{ 30 | protected: 31 | std::shared_ptr module_; 32 | llvm::Function *func_; 33 | llvm::BasicBlock *basicBlock_; 34 | 35 | public: 36 | LLVMFuncBuilder(std::shared_ptr module, llvm::FunctionType *funcType, std::string name); 37 | LLVMFuncBuilder(std::shared_ptr module, llvm::Function *func); 38 | 39 | void makeReturn(llvm::Value *value); 40 | 41 | LLVMModuleBuilder *getModuleBuilder(); 42 | 43 | llvm::BasicBlock *getBasicBlock(); 44 | 45 | llvm::Function *getFunc(); 46 | 47 | }; 48 | 49 | class LLVMExprBuilder { 50 | private: 51 | std::shared_ptr func_; 52 | public: 53 | LLVMExprBuilder(std::shared_ptr func); 54 | 55 | llvm::Value *makeConst(int value); 56 | llvm::Value *makeConst(float value); 57 | llvm::Value *makeConst(double value); 58 | llvm::Value *makeConst(llvm::StringRef str); 59 | 60 | llvm::Instruction *makeCalcOp(llvm::AddrSpaceCastInst::BinaryOps ops,llvm::Value *lhs,llvm::Value *rhs); 61 | 62 | llvm::Instruction *makeCalcOp(llvm::BasicBlock *block ,llvm::AddrSpaceCastInst::BinaryOps ops,llvm::Value *lhs,llvm::Value *rhs ); 63 | }; 64 | 65 | class LLVMStorage { 66 | public: 67 | std::shared_ptr module_; 68 | LLVMStorage(std::shared_ptr module); 69 | virtual llvm::AllocaInst *CreateAlloc(llvm::Type *DestTy) = 0; 70 | }; 71 | 72 | class LLVMHeapStorage : public LLVMStorage { 73 | public: 74 | LLVMHeapStorage(std::shared_ptr module); 75 | virtual llvm::AllocaInst *CreateAlloc(llvm::Type *DestTy); 76 | }; 77 | 78 | class LLVMStructDefMap; 79 | 80 | class LLVMVariable { 81 | protected: 82 | TYPE type_; 83 | std::shared_ptr module_; 84 | llvm::Value *value_; 85 | 86 | public: 87 | LLVMVariable(std::shared_ptr module, TYPE type); 88 | 89 | virtual void set(llvm::Value *newVal); 90 | 91 | virtual llvm::Value *get(); 92 | 93 | TYPE getType(); 94 | }; 95 | 96 | class FieldDefElem { 97 | public: 98 | std::string name; 99 | TYPE type; 100 | }; 101 | 102 | class LLVMStructDef { 103 | public: 104 | // using FieldDef = std::map; 105 | std::shared_ptr module_; 106 | using FieldDef = std::vector; 107 | llvm::StructType *structTy; 108 | std::string def_name_; 109 | FieldDef fields_; 110 | llvm::PointerType *structPtr; 111 | 112 | LLVMStructDef(std::shared_ptr module, std::string def_name, FieldDef fields); 113 | 114 | llvm::StructType *getStructTy(); 115 | llvm::PointerType *getStructPtr(); 116 | std::string getDefName(); 117 | 118 | int filedName2Index(std::string field_name); 119 | }; 120 | 121 | class LLVMStructDefMap { 122 | public: 123 | std::shared_ptr module_; 124 | std::map map; 125 | 126 | LLVMStructDefMap(std::shared_ptr module); 127 | 128 | virtual void set(std::string name, LLVMStructDef *struct_def); 129 | 130 | virtual LLVMStructDef *get(std::string name); 131 | 132 | void makeStructDef(std::string def_name, LLVMStructDef::FieldDef fields); 133 | }; 134 | 135 | class LLVMStructInitializer { 136 | public: 137 | TYPE type; 138 | 139 | LLVMStructInitializer(std::shared_ptr module, LLVMStructDef *struct_def); 140 | }; 141 | 142 | class LLVMStruct : public LLVMStructInitializer ,public LLVMVariable { 143 | private: 144 | LLVMStructDef *struct_def_; 145 | std::shared_ptr storage_; 146 | public: 147 | LLVMStruct(std::shared_ptr module, LLVMStructDef *struct_def, std::shared_ptr storage); 148 | 149 | virtual void set(std::string member_name, llvm::Value *newVal); 150 | virtual void set(llvm::Value *newVal); 151 | 152 | virtual llvm::Value *get(std::string member_name); 153 | virtual llvm::Value *get(); 154 | }; 155 | 156 | class Klass : public LLVMStruct { 157 | public: 158 | Klass(std::shared_ptr module, LLVMStructDef *struct_def, int klass_id, std::shared_ptr storage); 159 | }; 160 | 161 | class KlassDef : public LLVMStructDef { 162 | std::map> method_map; 163 | 164 | public: 165 | KlassDef(std::shared_ptr module, std::string name, FieldDef fields); 166 | 167 | void addMethod(std::string name, std::shared_ptr func); 168 | 169 | int getMethodId(std::string name); 170 | 171 | int getMethodCount(); 172 | 173 | std::map> getMethodMap(); 174 | }; 175 | 176 | class KlassDefMap { 177 | std::shared_ptr module_; 178 | std::map map; 179 | 180 | public: 181 | KlassDefMap(std::shared_ptr module); 182 | 183 | void set(std::string name, KlassDef *klass_def); 184 | 185 | KlassDef *get(std::string name); 186 | 187 | void makeKlassDef(std::string name, KlassDef::FieldDef fields); 188 | 189 | int getDefId(std::string name); 190 | 191 | int size(); 192 | 193 | std::map getMap(); 194 | }; 195 | 196 | class LLVMArray : public LLVMVariable { 197 | private: 198 | LLVMStructDef *struct_def_; 199 | llvm::AllocaInst *alloca_inst; 200 | llvm::AllocaInst *alloca_inst_ptr; 201 | int size_; 202 | 203 | public: 204 | LLVMArray(std::shared_ptr module, TYPE type, int size); 205 | 206 | llvm::ArrayType *getArrayType(); 207 | 208 | virtual void set(llvm::Value *index, llvm::Value *newVal); 209 | 210 | virtual llvm::Value *get(llvm::Value *index); 211 | 212 | llvm::PointerType *getArrayPtr(); 213 | }; 214 | 215 | class LLVMVariableMap; 216 | 217 | class VariableIndicator { 218 | protected: 219 | std::string name_; 220 | 221 | public: 222 | VariableIndicator(std::string name); 223 | 224 | virtual void set(LLVMVariableMap *target, llvm::Value *newVal); // visitor of Visitor Pattern 225 | virtual llvm::Value *get(LLVMVariableMap *target); // visitor of Visitor Pattern 226 | }; 227 | 228 | class StructIndicator : public VariableIndicator { 229 | std::string member_name_; 230 | 231 | public: 232 | StructIndicator(std::string var_name, std::string member_name); 233 | 234 | virtual void set(LLVMVariableMap *target, llvm::Value *newVal); // visitor of Visitor Pattern 235 | virtual llvm::Value *get(LLVMVariableMap *target); // visitor of Visitor Pattern 236 | }; 237 | 238 | class ArrayIndicator : public VariableIndicator { 239 | llvm::Value *index_; 240 | 241 | public: 242 | ArrayIndicator(std::string var_name, llvm::Value *index); 243 | 244 | virtual void set(LLVMVariableMap *target, llvm::Value *newVal); // visitor of Visitor Pattern 245 | virtual llvm::Value *get(LLVMVariableMap *target); // visitor of Visitor Pattern 246 | }; 247 | 248 | class LLVMVariableMap { 249 | public: 250 | std::shared_ptr module_; 251 | std::map map; 252 | std::shared_ptr struct_def_map_; 253 | std::shared_ptr klass_def_map_; 254 | 255 | LLVMVariableMap(std::shared_ptr module, std::shared_ptr struct_def_map, std::shared_ptr klass_def_map); 256 | 257 | virtual void makeVariable(std::string name ,TYPE type) = 0; 258 | 259 | void set(VariableIndicator *target, llvm::Value *newVal); // acceotor of Visitor Pattern 260 | 261 | llvm::Value *get(VariableIndicator *target); 262 | 263 | LLVMVariable *getVariable(std::string name); 264 | }; 265 | 266 | class LLVMLocalVariableMap : public LLVMVariableMap { 267 | public: 268 | LLVMLocalVariableMap(std::shared_ptr module, std::shared_ptr struct_def_map, std::shared_ptr klass_def_map); 269 | 270 | virtual void makeVariable(std::string name ,TYPE type); 271 | void makeClass(std::string name, KlassDef *klassDef, std::shared_ptr storage); 272 | void makeArray(std::string name, TYPE type, int size); 273 | }; 274 | 275 | llvm::PointerType *getOpequePtrType(llvm::LLVMContext *context); 276 | 277 | llvm::Value *makePrintf(std::shared_ptr module,std::shared_ptr builder, std::string printStr); // TODO delete lator 278 | llvm::Type *astType2LLVMType(std::shared_ptr module, TYPEKIND kind); 279 | 280 | int getFieldDistance(LLVMStructDef::FieldDef fields,std::string field_name); 281 | 282 | #define KLASS_ID_VAL_NAME "$ID" 283 | 284 | #endif /* __cplusplus */ 285 | 286 | #endif 287 | -------------------------------------------------------------------------------- /src/ast.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "mugicha.h" 5 | #include "support.h" 6 | #include "func.h" 7 | 8 | ASTNODE *make_astnode(){ 9 | ASTNODE *p; 10 | p = (ASTNODE *)malloc(sizeof(ASTNODE)); 11 | if(!p) ASSERT_FAIL("memory error"); 12 | 13 | p->super_class = NULL; 14 | p->type.kind = ANY; 15 | p->op = NONE; 16 | p->val.val.v = NULL; 17 | p->sym = NULL; 18 | p->left = NULL; 19 | p->right = NULL; 20 | p->set_args = NULL; 21 | p->condition = NULL; 22 | 23 | return p; 24 | } 25 | 26 | ASTNODE *make_ast_int(int val) 27 | { 28 | ASTNODE *np; 29 | int *vp; 30 | 31 | np = make_astnode(); 32 | 33 | np->op = VALUEDATA; 34 | np->val.type.kind = INT; 35 | np->val.val.i = val; 36 | np->left = NULL; 37 | np->right = NULL; 38 | 39 | return np; 40 | } 41 | 42 | ASTNODE *make_ast_double(double val) 43 | { 44 | ASTNODE *np; 45 | int *vp; 46 | 47 | np = make_astnode(); 48 | 49 | np->op = VALUEDATA; 50 | np->val.type.kind = DOUBLE; 51 | np->val.val.d = val; 52 | np->left = NULL; 53 | np->right = NULL; 54 | 55 | return np; 56 | } 57 | 58 | ASTNODE *make_ast_string(char *val) 59 | { 60 | ASTNODE *np; 61 | int *vp; 62 | 63 | np = make_astnode(); 64 | 65 | np->op = VALUEDATA; 66 | np->val.type.kind = STRING; 67 | np->val.val.s = val; 68 | np->left = NULL; 69 | np->right = NULL; 70 | 71 | return np; 72 | } 73 | 74 | ASTNODE *make_ast_bool(BOOL val) 75 | { 76 | ASTNODE *np; 77 | int *vp; 78 | 79 | np = make_astnode(); 80 | 81 | np->op = VALUEDATA; 82 | np->val.type.kind = BOOLTYPE; 83 | np->val.val.b = val; 84 | np->left = NULL; 85 | np->right = NULL; 86 | 87 | return np; 88 | } 89 | 90 | 91 | ASTNODE *make_ast_op(OPERATION op, ASTNODE *lhr, ASTNODE *rhr) 92 | { 93 | ASTNODE *np; 94 | 95 | 96 | np = make_astnode(); 97 | 98 | np->type.kind = ANY; 99 | np->op = op; 100 | np->left = lhr; 101 | np->right = rhr; 102 | 103 | 104 | return np; 105 | } 106 | 107 | ASTNODE *make_ast_get_var(char *name) 108 | { 109 | ASTNODE *np; 110 | 111 | TMP_DEBUGL; 112 | 113 | np = make_astnode(); 114 | np->type.kind = ANY;// TODO ここで型情報を設定しておくとあとで型の不整合エラーをチェックできるかもしれない 115 | np->op = GET_VAR; 116 | np->sym = lookup_symbol(name); 117 | np->left = NULL; 118 | np->right = NULL; 119 | 120 | return np; 121 | } 122 | 123 | ASTNODE *make_ast_cmd(OPERATION op, ASTNODE *argp) 124 | { 125 | ASTNODE *np; 126 | 127 | np = make_astnode(); 128 | 129 | np->type.kind = ANY; 130 | np->op = op; 131 | np->left = argp; 132 | np->right = NULL; 133 | 134 | return np; 135 | } 136 | 137 | ASTNODE *make_ast_if(ASTNODE *cond, ASTNODE *then_stmt, ASTNODE *else_stmt) 138 | { 139 | ASTNODE *np; 140 | 141 | np = make_astnode(); 142 | 143 | np->type.kind = ANY; 144 | np->op = IF_STMT; 145 | np->condition = cond; 146 | np->left = then_stmt; 147 | np->right = else_stmt; 148 | 149 | return np; 150 | } 151 | 152 | ASTNODE *make_ast_while(ASTNODE *cond, ASTNODE *loop_stmt) 153 | { 154 | ASTNODE *np; 155 | 156 | np = make_astnode(); 157 | 158 | np->type.kind = ANY; 159 | np->op = WHILE_STMT; 160 | np->condition = cond; 161 | np->left = loop_stmt; 162 | np->right = NULL; 163 | 164 | return np; 165 | } 166 | 167 | 168 | ASTNODE *make_ast_call_func(char *name, ASTNODE *set_args) 169 | { 170 | ASTNODE *np; 171 | FUNC *f; 172 | 173 | np = make_astnode(); 174 | np->type.kind = ANY; 175 | np->op = CALL_FUNC; 176 | np->sym = lookup_make_symbol(name); 177 | f = lookup_func(np->sym); 178 | np->set_args = set_args; 179 | 180 | // printf("call func symbol = %s",symbol_description(np->sym)); 181 | 182 | // print_astnodeln(0, np); 183 | 184 | 185 | return np; 186 | } 187 | 188 | ASTNODE *make_ast_call_method(char *reviever_name, char *method_name, ASTNODE *set_args) 189 | { 190 | ASTNODE *np; 191 | FUNC *f; 192 | 193 | np = make_astnode(); 194 | np->type.kind = ANY; 195 | np->op = CALL_METHOD; 196 | np->reciever = lookup_make_symbol(reviever_name); 197 | np->sym = lookup_make_symbol(method_name); 198 | f = lookup_func(np->sym); 199 | np->set_args = set_args; 200 | 201 | return np; 202 | } 203 | 204 | ASTNODE *make_ast_def_func(char *name, ASTNODE *def_args, char *type_name, ASTNODE *body) 205 | { 206 | ASTNODE *np; 207 | 208 | 209 | np = make_astnode(); 210 | 211 | np->type.kind = get_type_by_name(type_name); 212 | np->op = DEF_FUNC; 213 | np->sym = lookup_make_symbol(name); 214 | np->left = NULL; 215 | np->right = NULL; 216 | 217 | make_func(np->sym, np->type, np, body, def_args); 218 | 219 | return np; 220 | } 221 | 222 | ASTNODE *make_ast_def_method(char *reciever_name, char *method_name, ASTNODE *def_args, char *type_name, ASTNODE *body) 223 | { 224 | ASTNODE *np; 225 | 226 | np = make_astnode(); 227 | 228 | np->reciever_type.kind = KLASS; 229 | np->reciever_type.klass = lookup_make_symbol(reciever_name); 230 | np->type.kind = get_type_by_name(type_name); 231 | np->op = DEF_METHOD; 232 | np->sym = lookup_make_symbol(method_name); 233 | np->left = NULL; 234 | np->right = NULL; 235 | 236 | make_method(np->reciever_type, np->sym, np->type, np, body, def_args); 237 | 238 | return np; 239 | } 240 | 241 | ASTNODE *make_ast_def_class(char *name, char *super_name, ASTNODE *def_vars) 242 | { 243 | ASTNODE *np; 244 | 245 | 246 | np = make_astnode(); 247 | 248 | np->type.kind = ANY; 249 | np->op = DEF_CLASS; 250 | np->sym = lookup_make_symbol(name); 251 | np->super_class = super_name ? lookup_make_symbol(super_name) : NULL; 252 | np->def_vars = def_vars; 253 | 254 | return np; 255 | } 256 | 257 | ASTNODE *make_ast_new_class(char *name, ASTNODE *set_args) 258 | { 259 | ASTNODE *np; 260 | 261 | 262 | np = make_astnode(); 263 | 264 | np->type.kind = get_type_by_name(name); 265 | if(np->type.kind == KLASS) np->type.klass = lookup_make_symbol(name); 266 | np->op = NEW_CLASS; 267 | np->sym = NULL; 268 | np->left = NULL; 269 | np->right = NULL; 270 | np->set_args = set_args; 271 | 272 | return np; 273 | } 274 | 275 | 276 | ASTNODE *make_ast_def_var(char *name, char *type_name) 277 | { 278 | ASTNODE *np; 279 | 280 | 281 | np = make_astnode(); 282 | 283 | np->type.kind = get_type_by_name(type_name); 284 | if(np->type.kind == KLASS) np->type.klass = lookup_make_symbol(type_name); 285 | np->op = DEF_VAR; 286 | np->sym = lookup_make_symbol(name); 287 | np->left = NULL; 288 | np->right = NULL; 289 | 290 | return np; 291 | } 292 | 293 | ASTNODE *make_ast_def_array(char *name, char *type_name, ASTNODE *size) 294 | { 295 | ASTNODE *np; 296 | 297 | TMP_DEBUGL; 298 | 299 | np = make_astnode(); 300 | 301 | np->type.kind = ARRAY; 302 | np->type.elem_kind = get_type_by_name(type_name); 303 | if(np->type.elem_kind == KLASS) np->type.klass = lookup_make_symbol(type_name); 304 | np->op = DEF_VAR; 305 | np->sym = lookup_make_symbol(name); 306 | np->left = size; 307 | np->right = NULL; 308 | 309 | return np; 310 | } 311 | 312 | ASTNODE *make_ast_set_var(char *name, ASTNODE *newval) 313 | { 314 | ASTNODE *np; 315 | SYMBOL *s; 316 | 317 | s = lookup_symbol(name); 318 | 319 | np = make_astnode(); 320 | 321 | np->type.kind = ANY; 322 | np->op = SET_VAR; 323 | np->sym = s; 324 | np->left = newval; 325 | np->right = NULL; 326 | 327 | // printf("symbol = %s",symbol_description(np->sym)); 328 | 329 | // print_astnodeln(0, np); 330 | 331 | return np; 332 | } 333 | 334 | ASTNODE *make_ast_set_member_var(char *var_name, char *member_name, ASTNODE *newval) 335 | { 336 | ASTNODE *np; 337 | SYMBOL *s, *mems; 338 | 339 | TMP_DEBUGL; 340 | 341 | s = lookup_symbol(var_name); 342 | mems = lookup_symbol(member_name); 343 | 344 | np = make_astnode(); 345 | 346 | np->type.kind = ANY; 347 | np->op = SET_MEMBER_VAR; 348 | np->sym = s; 349 | np->member = mems; 350 | np->left = newval; 351 | np->right = NULL; 352 | 353 | // printf("symbol = %s",symbol_description(np->sym)); 354 | 355 | // print_astnodeln(0, np); 356 | 357 | return np; 358 | } 359 | 360 | ASTNODE *make_ast_set_array_var(char *var_name, ASTNODE *index_node, ASTNODE *newval) 361 | { 362 | ASTNODE *np; 363 | SYMBOL *s, *mems; 364 | 365 | TMP_DEBUGL; 366 | 367 | s = lookup_symbol(var_name); 368 | 369 | np = make_astnode(); 370 | 371 | np->type.kind = ANY; 372 | np->op = SET_ARRAY_VAR; 373 | np->sym = s; 374 | np->left = newval; 375 | np->right = index_node; 376 | 377 | // printf("symbol = %s",symbol_description(np->sym)); 378 | 379 | // print_astnodeln(0, np); 380 | 381 | return np; 382 | } 383 | 384 | ASTNODE *make_ast_get_member_var(char *var_name, char *member_name) 385 | { 386 | ASTNODE *np; 387 | SYMBOL *s, *mems; 388 | 389 | TMP_DEBUGL; 390 | 391 | s = lookup_make_symbol(var_name); 392 | mems = lookup_symbol(member_name); 393 | 394 | TMP_DEBUGS(var_name); 395 | 396 | np = make_astnode(); 397 | 398 | np->type.kind = ANY; 399 | np->op = GET_MEMBER_VAR; 400 | np->sym = s; 401 | np->member = mems; 402 | np->left = NULL; 403 | np->right = NULL; 404 | 405 | // printf("symbol = %s",symbol_description(np->sym)); 406 | 407 | // print_astnodeln(0, np); 408 | 409 | return np; 410 | } 411 | 412 | ASTNODE *make_ast_get_array_var(char *var_name, ASTNODE *index_node) 413 | { 414 | ASTNODE *np; 415 | SYMBOL *s, *mems; 416 | 417 | TMP_DEBUGL; 418 | 419 | s = lookup_make_symbol(var_name); 420 | 421 | TMP_DEBUGS(var_name); 422 | 423 | np = make_astnode(); 424 | 425 | np->type.kind = ANY; 426 | np->op = GET_ARRAY_VAR; 427 | np->sym = s; 428 | np->left = index_node; 429 | np->right = NULL; 430 | 431 | // printf("symbol = %s",symbol_description(np->sym)); 432 | 433 | // print_astnodeln(0, np); 434 | 435 | return np; 436 | } 437 | 438 | ASTNODE *search_ast_by_sym(ASTNODE *ap, char *sym_name) 439 | { 440 | if(!ap) return NULL; 441 | 442 | if(ap->sym){ 443 | if(!strcmp(ap->sym->name, sym_name)){ 444 | return ap; 445 | } 446 | } 447 | 448 | TMP_DEBUGL; 449 | 450 | ASTNODE *l = search_ast_by_sym(ap->left, sym_name); 451 | if(l) return l; 452 | 453 | TMP_DEBUGL; 454 | ASTNODE *r = search_ast_by_sym(ap->right, sym_name); 455 | if(r) return r; 456 | 457 | TMP_DEBUGL; 458 | return NULL; 459 | } 460 | 461 | 462 | void print_astnode(int depth, ASTNODE *np) 463 | { 464 | int i; 465 | char *t, *o ,*v; 466 | 467 | for(i = 0 ; i < depth ; i++){ 468 | printf(" "); 469 | } 470 | 471 | TMP_DEBUGL; 472 | TMP_DEBUGP(np); 473 | TMP_DEBUGI(np->op); 474 | TMP_DEBUGI(np->type.kind); 475 | t = get_type_description(np->type.kind); 476 | TMP_DEBUGL; 477 | o = get_op_description(np->op); 478 | TMP_DEBUGL; 479 | v = value_description(np->val); 480 | TMP_DEBUGL; 481 | printf("ast type.kind = %s oper = %s val = %s ",t ,o, v); 482 | TMP_DEBUGL; 483 | 484 | 485 | 486 | if(np->op == DEF_VAR){ 487 | printf("/ val symbol : %s / ",symbol_description(np->sym)); 488 | } 489 | if(np->op == DEF_FUNC){ 490 | printf("/ func symbol : %s / ",symbol_description(np->sym)); 491 | TMP_DEBUGL; 492 | FUNC *f = lookup_func(np->sym); 493 | TMP_DEBUGL; 494 | if(f->body){ 495 | TMP_DEBUGP(f->body); 496 | printf("\n"); 497 | print_ast(depth + 1, f->body); 498 | } 499 | TMP_DEBUGL; 500 | } 501 | TMP_DEBUGL; 502 | 503 | /* 504 | printf("addr:%p type.kind = %s oper = %s val = %s left = %p right = %p\n", 505 | np , 506 | type_a[np->type], 507 | op_a[np->op], 508 | value_description(np->type, np->val), 509 | np->left, 510 | np->right 511 | ); 512 | */ 513 | 514 | } 515 | void print_astnodeln(int depth, ASTNODE *np) 516 | { 517 | print_astnode(depth, np); 518 | printf("\n"); 519 | } 520 | 521 | void print_ast(int depth, ASTNODE *np) 522 | { 523 | TMP_DEBUGL; 524 | TMP_DEBUGP(np); 525 | print_astnodeln(depth, np); 526 | TMP_DEBUGL; 527 | 528 | if(np->left) 529 | print_ast(depth + 1, np->left); 530 | if(np->right) 531 | print_ast(depth + 1, np->right); 532 | TMP_DEBUGL; 533 | } 534 | -------------------------------------------------------------------------------- /src/llvm_builder.cpp: -------------------------------------------------------------------------------- 1 | //===- examples/ModuleMaker/ModuleMaker.cpp - Example project ---*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This programs is a simple example that creates an LLVM module "from scratch", 11 | // emitting it as a bitcode file to standard out. This is just to show how 12 | // LLVM projects work and to demonstrate some of the LLVM APIs. 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | #include "llvm/Bitcode/ReaderWriter.h" 17 | #include "llvm/IR/BasicBlock.h" 18 | #include "llvm/IR/Constants.h" 19 | #include "llvm/IR/DerivedTypes.h" 20 | #include "llvm/IR/Function.h" 21 | #include "llvm/IR/InstrTypes.h" 22 | #include "llvm/IR/Instruction.h" 23 | #include "llvm/IR/Instructions.h" 24 | #include "llvm/IR/LLVMContext.h" 25 | #include "llvm/IR/Module.h" 26 | #include "llvm/IR/Type.h" 27 | #include "llvm/Support/raw_ostream.h" 28 | 29 | #include "llvm/IR/Module.h" 30 | #include "llvm/IR/TypeBuilder.h" 31 | #include "llvm/IR/Function.h" 32 | #include "llvm/IR/PassManager.h" 33 | #include "llvm/IR/CallingConv.h" 34 | #include "llvm/IR/Verifier.h" 35 | #include "llvm/IR/IRPrintingPasses.h" 36 | #include "llvm/IR/IRBuilder.h" 37 | #include "llvm/IR/DerivedTypes.h" 38 | #include "llvm/IR/DataLayout.h" 39 | 40 | #include "llvm/ADT/STLExtras.h" 41 | 42 | #include "llvm/Bitcode/ReaderWriter.h" 43 | 44 | #include "llvm/Support/raw_ostream.h" 45 | #include "llvm/Support/type_traits.h" 46 | #include "llvm/Support/ToolOutputFile.h" 47 | #include "llvm/Support/FormattedStream.h" 48 | #include "llvm/Support/FileSystem.h" 49 | 50 | #include "llvm/IR/Argument.h" 51 | #include 52 | 53 | #include "llvm_builder.h" 54 | #include "support.h" 55 | #include "symbol.h" 56 | 57 | llvm::PointerType *getOpequePtrType(llvm::LLVMContext *context){ 58 | auto opequeType = llvm::Type::getInt8Ty(*context); 59 | auto opequePtrType = llvm::PointerType::getUnqual(opequeType); 60 | 61 | return opequePtrType; 62 | } 63 | 64 | llvm::Type *astType2LLVMType(std::shared_ptr module, TYPEKIND kind){ 65 | switch(kind){ 66 | case INT: 67 | case BOOLTYPE: 68 | return llvm::Type::getInt32Ty(*module->getContext()); 69 | case DOUBLE: 70 | return llvm::Type::getDoubleTy(*module->getContext()); 71 | case STRING: 72 | return llvm::Type::getInt8PtrTy(*module->getContext()); 73 | default: 74 | ASSERT_FAIL_BLOCK(); 75 | } 76 | } 77 | 78 | // class LLVMModuleBuilder { 79 | // protected: 80 | // std::shared_ptr module_; 81 | // std::shared_ptr context_; 82 | // std::shared_ptr> builder_; 83 | 84 | // public: 85 | LLVMModuleBuilder::LLVMModuleBuilder(std::string name, std::shared_ptr context){ 86 | context_ = context; 87 | module_ = std::make_shared(name, *context); 88 | builder_ = std::make_shared>(*context); 89 | } 90 | 91 | llvm::Module *LLVMModuleBuilder::getModule(){ 92 | return module_.get(); 93 | } 94 | 95 | llvm::LLVMContext *LLVMModuleBuilder::getContext(){ 96 | return context_.get(); 97 | } 98 | 99 | llvm::IRBuilder<> *LLVMModuleBuilder::getBuilder(){ 100 | return builder_.get(); 101 | } 102 | 103 | llvm::Value *LLVMModuleBuilder::makePrintf(std::vector values){ 104 | // printf の関数準備 105 | std::vector args; 106 | args.push_back(llvm::Type::getInt8PtrTy(*context_)); 107 | llvm::FunctionType *printfType = 108 | llvm::FunctionType::get(builder_->getInt32Ty(), args, true); 109 | llvm::Constant *printfFunc = 110 | module_->getOrInsertFunction("printf", printfType); 111 | 112 | return builder_->CreateCall(printfFunc, values); 113 | } 114 | 115 | llvm::Value *LLVMModuleBuilder::makeMalloc(llvm::Constant *AllocSize, llvm::Type *DestTy){ 116 | // printf の関数準備 117 | auto ITy = llvm::Type::getInt32Ty(*context_); 118 | auto castedAllocSize = llvm::ConstantExpr::getTruncOrBitCast(AllocSize, ITy); 119 | std::vector fmalloc_args({castedAllocSize}); 120 | std::vector args; 121 | args.push_back(builder_->getInt32Ty()); 122 | llvm::FunctionType *printfType = 123 | llvm::FunctionType::get(llvm::Type::getInt8PtrTy(*context_), args, true); 124 | llvm::Constant *func = 125 | module_->getOrInsertFunction("malloc", printfType); 126 | 127 | return builder_->CreateCall(func, fmalloc_args); 128 | } 129 | 130 | llvm::AllocaInst *LLVMModuleBuilder::makeMallocForType(llvm::Type *DestTy){ 131 | auto AllocSize = llvm::ConstantExpr::getSizeOf(DestTy); 132 | auto inst = makeMalloc(AllocSize, DestTy); 133 | auto destPtrTy = llvm::PointerType::getUnqual(DestTy); 134 | return (llvm::AllocaInst *)builder_->CreateBitCast(inst, destPtrTy); 135 | } 136 | 137 | LLVMFuncBuilder::LLVMFuncBuilder(std::shared_ptr module, llvm::FunctionType *funcType, std::string name){ 138 | module_ = module; 139 | func_ = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, name, module_->getModule()); 140 | basicBlock_ = llvm::BasicBlock::Create(*module_->getContext(), "EntryBlock", func_); 141 | module->getBuilder()->SetInsertPoint(basicBlock_); 142 | } 143 | 144 | LLVMFuncBuilder::LLVMFuncBuilder(std::shared_ptr module, llvm::Function *func) 145 | { 146 | module_ = module; 147 | func_ = func; 148 | basicBlock_ = module_->getBuilder()->GetInsertBlock(); 149 | // module->getBuilder()->SetInsertPoint(basicBlock_); 150 | } 151 | 152 | // void LLVMFuncBuilder::makeReturn(llvm::Value *value){ 153 | // return basicBlock_->getInstList().push_back(llvm::ReturnInst::Create(*module_->getContext(), value)); 154 | // } 155 | void LLVMFuncBuilder::makeReturn(llvm::Value *value){ 156 | auto iBuilder = module_->getBuilder(); 157 | iBuilder->GetInsertBlock()->getInstList().push_back(llvm::ReturnInst::Create(*module_->getContext(), value)); 158 | // return basicBlock->getInstList().push_back(llvm::ReturnInst::Create(*module_->getContext(), value)); 159 | } 160 | 161 | LLVMModuleBuilder *LLVMFuncBuilder::getModuleBuilder(){ 162 | return module_.get(); 163 | } 164 | 165 | llvm::BasicBlock *LLVMFuncBuilder::getBasicBlock(){ 166 | return basicBlock_; 167 | } 168 | 169 | llvm::Function *LLVMFuncBuilder::getFunc(){ 170 | return func_; 171 | } 172 | 173 | LLVMExprBuilder::LLVMExprBuilder(std::shared_ptr func){ 174 | func_ = func; 175 | } 176 | 177 | llvm::Value *LLVMExprBuilder::makeConst(int value){ 178 | llvm::LLVMContext *context = func_->getModuleBuilder()->getContext(); 179 | 180 | llvm::Value *val = llvm::ConstantInt::get(llvm::Type::getInt32Ty(*context), value); 181 | 182 | return val; 183 | } 184 | 185 | llvm::Value *LLVMExprBuilder::makeConst(float value){ 186 | llvm::LLVMContext *context = func_->getModuleBuilder()->getContext(); 187 | 188 | llvm::Value *val = llvm::ConstantFP::get(llvm::Type::getFloatTy(*context), value); 189 | 190 | return val; 191 | } 192 | 193 | llvm::Value *LLVMExprBuilder::makeConst(double value){ 194 | 195 | llvm::LLVMContext *context = func_->getModuleBuilder()->getContext(); 196 | 197 | 198 | llvm::Value *val = llvm::ConstantFP::get(llvm::Type::getDoubleTy(*context), value); 199 | 200 | 201 | return val; 202 | } 203 | 204 | llvm::Value *LLVMExprBuilder::makeConst(llvm::StringRef str){ 205 | llvm::IRBuilder<> *builder = func_->getModuleBuilder()->getBuilder(); 206 | 207 | llvm::Value *val = builder->CreateGlobalStringPtr(str); 208 | 209 | return val; 210 | } 211 | 212 | // 値を作成して呼び出し元で使用するパターン 213 | llvm::Instruction *LLVMExprBuilder::makeCalcOp(llvm::AddrSpaceCastInst::BinaryOps ops,llvm::Value *lhs,llvm::Value *rhs){ 214 | 215 | llvm::LLVMContext *context = func_->getModuleBuilder()->getContext(); 216 | llvm::BasicBlock *block = func_->getBasicBlock(); 217 | 218 | 219 | llvm::Instruction *inst = llvm::BinaryOperator::Create(ops, lhs, rhs, "calcresult"); 220 | 221 | 222 | block->getInstList().push_back(inst); //この操作を挟まないとうまく行かず 223 | 224 | return inst; 225 | } 226 | 227 | LLVMStorage::LLVMStorage(std::shared_ptr module){ 228 | TMP_DEBUGP(module.get()); 229 | module_ = module; 230 | } 231 | 232 | LLVMHeapStorage::LLVMHeapStorage(std::shared_ptr module) : LLVMStorage(module) { 233 | } 234 | 235 | llvm::AllocaInst *LLVMHeapStorage::CreateAlloc(llvm::Type *DestTy){ 236 | TMP_DEBUGL; 237 | auto ret = module_->makeMallocForType(DestTy); 238 | TMP_DEBUGL; 239 | return ret; 240 | } 241 | 242 | LLVMVariable::LLVMVariable(std::shared_ptr module, TYPE type){ 243 | type_ = type; 244 | module_ = module; 245 | 246 | TMP_DEBUGI(type.kind); 247 | DEBUGS(get_type_description(type.kind)); 248 | switch(type.kind){ 249 | case INT: 250 | case BOOLTYPE: 251 | value_ = module->getBuilder()->CreateAlloca(llvm::Type::getInt32Ty(*module->getContext()), 0); 252 | break; 253 | case DOUBLE: 254 | value_ = module->getBuilder()->CreateAlloca(llvm::Type::getDoubleTy(*module->getContext()), 0); 255 | break; 256 | case STRING: 257 | value_ = module->getBuilder()->CreateAlloca(llvm::Type::getInt8PtrTy(*module->getContext()), 0); 258 | break; 259 | case ARRAY: 260 | case KLASS: 261 | value_ = module->getBuilder()->CreateAlloca(getOpequePtrType(module->getContext()), 0); 262 | break; 263 | default: 264 | ASSERT_FAIL_BLOCK(); 265 | } 266 | TMP_DEBUGL; 267 | } 268 | 269 | void LLVMVariable::set(llvm::Value *newVal){ 270 | TMP_DEBUGL; 271 | module_->getBuilder()->CreateStore(newVal, value_); 272 | } 273 | 274 | llvm::Value *LLVMVariable::get(){ 275 | TMP_DEBUGL; 276 | return module_->getBuilder()->CreateLoad(value_); 277 | } 278 | 279 | TYPE LLVMVariable::getType(){ 280 | return type_; 281 | } 282 | 283 | LLVMStructDef::LLVMStructDef(std::shared_ptr module, std::string def_name, FieldDef fields){ 284 | 285 | module_ = module; 286 | def_name_ = def_name; 287 | fields_ = fields; 288 | 289 | std::vector fieldsvec; 290 | for(auto itr = fields.begin(); itr != fields.end(); ++itr) { 291 | auto type = astType2LLVMType(module_, itr->type.kind); 292 | fieldsvec.push_back(type); 293 | } 294 | 295 | structTy = llvm::StructType::create(fieldsvec, def_name, false); 296 | structPtr = llvm::PointerType::getUnqual(structTy); 297 | } 298 | 299 | llvm::StructType *LLVMStructDef::getStructTy(){ 300 | return structTy; 301 | } 302 | 303 | llvm::PointerType *LLVMStructDef::getStructPtr(){ 304 | return structPtr; 305 | } 306 | 307 | std::string LLVMStructDef::getDefName(){ 308 | return def_name_; 309 | } 310 | 311 | int LLVMStructDef::filedName2Index(std::string field_name){ 312 | return getFieldDistance(fields_, field_name); 313 | } 314 | 315 | LLVMStructDefMap::LLVMStructDefMap(std::shared_ptr module){ 316 | module_ = module; 317 | } 318 | 319 | void LLVMStructDefMap::set(std::string name, LLVMStructDef *struct_def){ 320 | TMP_DEBUGL; 321 | map[name] = struct_def; 322 | } 323 | 324 | LLVMStructDef *LLVMStructDefMap::get(std::string name){ 325 | TMP_DEBUGL; 326 | return map[name]; 327 | } 328 | 329 | void LLVMStructDefMap::makeStructDef(std::string def_name, LLVMStructDef::FieldDef fields){ 330 | LLVMStructDef *sd = new LLVMStructDef(module_, def_name, fields); 331 | map[def_name] = sd; 332 | } 333 | 334 | LLVMStructInitializer::LLVMStructInitializer(std::shared_ptr module, LLVMStructDef *struct_def){ 335 | type.kind = KLASS; 336 | type.klass = lookup_symbol(struct_def->getDefName().c_str()); 337 | TMP_DEBUGS(type.klass->name); 338 | } 339 | 340 | LLVMStruct::LLVMStruct(std::shared_ptr module,LLVMStructDef *struct_def, std::shared_ptr storage) : LLVMStructInitializer(module, struct_def) ,LLVMVariable(module, type) { 341 | TMP_DEBUGL; 342 | struct_def_ = struct_def; 343 | storage_ = storage; 344 | auto iBuilder = module_->getBuilder(); 345 | TMP_DEBUGL; 346 | TMP_DEBUGP(storage_.get()); 347 | auto alloca_inst= storage->CreateAlloc(struct_def->getStructTy()); 348 | TMP_DEBUGL; 349 | 350 | auto ptr = llvm::PointerType::getUnqual(struct_def->getStructPtr()); 351 | auto castedVal = iBuilder->CreateBitCast(value_, ptr); 352 | 353 | TMP_DEBUGL; 354 | 355 | iBuilder->CreateStore(alloca_inst, castedVal); 356 | TMP_DEBUGL; 357 | } 358 | 359 | void LLVMStruct::set(std::string member_name, llvm::Value *newVal){ 360 | TMP_DEBUGL; 361 | auto iBuilder = module_->getBuilder(); 362 | 363 | TMP_DEBUGL; 364 | auto ptrptr = llvm::PointerType::getUnqual(struct_def_->getStructPtr()); 365 | auto castedVal = iBuilder->CreateBitCast(value_, ptrptr); 366 | TMP_DEBUGL; 367 | auto ptr = iBuilder->CreateLoad(castedVal); 368 | TMP_DEBUGL; 369 | auto field_i = struct_def_->filedName2Index(member_name); 370 | 371 | TMP_DEBUGL; 372 | auto structTy = struct_def_->getStructTy(); 373 | TMP_DEBUGL; 374 | auto gep = iBuilder->CreateStructGEP(structTy, ptr, field_i); 375 | TMP_DEBUGL; 376 | auto store = iBuilder->CreateStore(newVal, gep); 377 | TMP_DEBUGL; 378 | } 379 | 380 | void LLVMStruct::set(llvm::Value *newVal){ 381 | TMP_DEBUGL; 382 | 383 | module_->getBuilder()->CreateStore(newVal, value_); 384 | TMP_DEBUGL; 385 | // value_ = (llvm::AllocaInst *)newVal; 386 | } 387 | 388 | llvm::Value *LLVMStruct::get(std::string member_name){ 389 | TMP_DEBUGL; 390 | auto iBuilder = module_->getBuilder(); 391 | auto structTy = struct_def_->getStructTy(); 392 | 393 | auto ptrptr = llvm::PointerType::getUnqual(struct_def_->getStructPtr()); 394 | auto castedVal = iBuilder->CreateBitCast(value_, ptrptr); 395 | auto ptr = iBuilder->CreateLoad(castedVal); 396 | auto field_i = struct_def_->filedName2Index(member_name); 397 | 398 | auto load = iBuilder->CreateLoad( iBuilder->CreateStructGEP(structTy, ptr, field_i)); 399 | 400 | return load; 401 | } 402 | 403 | llvm::Value *LLVMStruct::get(){ 404 | return module_->getBuilder()->CreateLoad(value_); 405 | // return value_; 406 | } 407 | 408 | Klass::Klass(std::shared_ptr module, LLVMStructDef *struct_def, int klass_id, std::shared_ptr storage) : LLVMStruct(module ,struct_def, storage){ 409 | llvm::Value *kid = llvm::ConstantInt::get(llvm::Type::getInt32Ty(*module_->getContext()), klass_id); 410 | set(KLASS_ID_VAL_NAME, kid); 411 | } 412 | 413 | 414 | llvm::ArrayType *LLVMArray::getArrayType(){ 415 | auto elem_type = astType2LLVMType(module_, type_.elem_kind); 416 | auto atype = llvm::ArrayType::get(elem_type, size_); 417 | 418 | return atype; 419 | } 420 | 421 | KlassDef::KlassDef(std::shared_ptr module, std::string name, FieldDef fields) : LLVMStructDef(module, name, fields) { 422 | } 423 | 424 | void KlassDef::addMethod(std::string name, std::shared_ptr func){ 425 | method_map[def_name_] = func; 426 | } 427 | 428 | int KlassDef::getMethodId(std::string name){ 429 | auto iter = method_map.find(def_name_); 430 | return std::distance(method_map.begin(), iter); 431 | } 432 | 433 | int KlassDef::getMethodCount(){ 434 | return method_map.size(); 435 | } 436 | 437 | std::map> KlassDef::getMethodMap(){ 438 | return method_map; 439 | } 440 | 441 | KlassDefMap::KlassDefMap(std::shared_ptr module){ 442 | module_ = module; 443 | } 444 | 445 | void KlassDefMap::set(std::string name, KlassDef *klass_def){ 446 | TMP_DEBUGS(name.c_str()); 447 | TMP_DEBUGP(&map); 448 | map[name] = klass_def; 449 | } 450 | 451 | int KlassDefMap::size(){ 452 | return map.size(); 453 | } 454 | 455 | KlassDef *KlassDefMap::get(std::string name){ 456 | TMP_DEBUGL; 457 | TMP_DEBUGS(name.c_str()); 458 | TMP_DEBUGP(&map); 459 | auto def = map[name]; 460 | 461 | if(!def) ASSERT_FAIL_BLOCK(); 462 | 463 | return def; 464 | } 465 | 466 | void KlassDefMap::makeKlassDef(std::string name, KlassDef::FieldDef fields){ 467 | TMP_DEBUGS(name.c_str()); 468 | TMP_DEBUGP(&map); 469 | map[name] = new KlassDef(module_, name, fields); 470 | TMP_DEBUGP(&map); 471 | } 472 | 473 | int KlassDefMap::getDefId(std::string name){ 474 | auto iter = map.find(name); 475 | return std::distance(map.begin(), iter); 476 | } 477 | 478 | std::map KlassDefMap::getMap(){ 479 | return map; 480 | } 481 | 482 | LLVMArray::LLVMArray(std::shared_ptr module, TYPE type, int size) : LLVMVariable(module, type) { 483 | TMP_DEBUGL; 484 | size_ = size; 485 | auto iBuilder = module_->getBuilder(); 486 | auto atype = getArrayType(); 487 | 488 | alloca_inst= iBuilder->CreateAlloca(atype, 0); 489 | TMP_DEBUGL; 490 | // 491 | auto ptr = llvm::PointerType::getUnqual(getArrayPtr()); 492 | 493 | auto castedVal = iBuilder->CreateBitCast(value_, ptr); 494 | // 495 | TMP_DEBUGL; 496 | 497 | iBuilder->CreateStore(alloca_inst, castedVal); 498 | TMP_DEBUGL; 499 | } 500 | 501 | void LLVMArray::set(llvm::Value *index, llvm::Value *newVal){ 502 | TMP_DEBUGL; 503 | auto iBuilder = module_->getBuilder(); 504 | 505 | TMP_DEBUGL; 506 | auto ptrptr = llvm::PointerType::getUnqual(getArrayPtr()); 507 | auto castedVal = iBuilder->CreateBitCast(value_, ptrptr); 508 | TMP_DEBUGL; 509 | auto ptr = iBuilder->CreateLoad(castedVal); 510 | TMP_DEBUGL; 511 | llvm::ConstantInt* CI = llvm::dyn_cast(index); 512 | if (!CI) { 513 | ASSERT_FAIL_BLOCK(); 514 | } 515 | auto field_i = CI->getSExtValue(); 516 | // auto field_i = index; 517 | 518 | TMP_DEBUGL; 519 | auto structTy = getArrayType(); 520 | TMP_DEBUGL; 521 | auto gep = iBuilder->CreateStructGEP(structTy, ptr, field_i); 522 | 523 | auto store = iBuilder->CreateStore(newVal, gep); 524 | TMP_DEBUGL; 525 | } 526 | 527 | llvm::Value *LLVMArray::get(llvm::Value *index){ 528 | TMP_DEBUGL; 529 | auto iBuilder = module_->getBuilder(); 530 | TMP_DEBUGL; 531 | auto structTy = getArrayType(); 532 | 533 | TMP_DEBUGL; 534 | auto ptrptr = llvm::PointerType::getUnqual(getArrayPtr()); 535 | TMP_DEBUGL; 536 | auto castedVal = iBuilder->CreateBitCast(value_, ptrptr); 537 | TMP_DEBUGL; 538 | auto ptr = iBuilder->CreateLoad(castedVal); 539 | TMP_DEBUGL; 540 | llvm::ConstantInt* CI = llvm::dyn_cast(index); 541 | if (!CI) { 542 | ASSERT_FAIL_BLOCK(); 543 | } 544 | auto field_i = CI->getSExtValue(); 545 | TMP_DEBUGI(field_i); 546 | 547 | TMP_DEBUGL; 548 | auto gep = iBuilder->CreateStructGEP(structTy, ptr, field_i); 549 | auto load = iBuilder->CreateLoad( gep); 550 | TMP_DEBUGL; 551 | 552 | return load; 553 | } 554 | 555 | llvm::PointerType *LLVMArray::getArrayPtr(){ 556 | auto atype = getArrayType(); 557 | auto ptr = llvm::PointerType::getUnqual(atype); 558 | return ptr; 559 | } 560 | 561 | LLVMVariableMap::LLVMVariableMap(std::shared_ptr module, std::shared_ptr struct_def_map, std::shared_ptr klass_def_map){ 562 | module_ = module; 563 | struct_def_map_ = struct_def_map; 564 | klass_def_map_ = klass_def_map; 565 | } 566 | 567 | void LLVMVariableMap::set(VariableIndicator *target, llvm::Value *newVal){ 568 | TMP_DEBUGL; 569 | target->set(this, newVal); 570 | TMP_DEBUGL; 571 | } 572 | 573 | llvm::Value *LLVMVariableMap::get(VariableIndicator *target){ 574 | TMP_DEBUGL; 575 | return target->get(this); 576 | } 577 | 578 | LLVMVariable *LLVMVariableMap::LLVMVariableMap::getVariable(std::string name){ 579 | TMP_DEBUGP(map[name]); 580 | return map[name]; 581 | } 582 | 583 | LLVMLocalVariableMap::LLVMLocalVariableMap(std::shared_ptr module, std::shared_ptr struct_def_map, std::shared_ptr klass_def_map) : LLVMVariableMap(module ,struct_def_map, klass_def_map){ 584 | 585 | } 586 | 587 | void LLVMLocalVariableMap::makeVariable(std::string name ,TYPE type){ 588 | map[name] = new LLVMVariable(module_, type); 589 | } 590 | 591 | void LLVMLocalVariableMap::makeClass(std::string name, KlassDef *klassDef, std::shared_ptr storage){ 592 | TMP_DEBUGL; 593 | auto klassId = klass_def_map_->getDefId(klassDef->getDefName()); 594 | auto c = new Klass(module_, klassDef, klassId, storage); 595 | map[name] = c; 596 | TMP_DEBUGL; 597 | } 598 | 599 | void LLVMLocalVariableMap::makeArray(std::string name, TYPE type, int size){ 600 | TMP_DEBUGL; 601 | map[name] = new LLVMArray(module_, type, size); 602 | TMP_DEBUGL; 603 | } 604 | 605 | VariableIndicator::VariableIndicator(std::string name){ 606 | name_ = name; 607 | } 608 | 609 | void VariableIndicator::set(LLVMVariableMap *target, llvm::Value *newVal){ 610 | TMP_DEBUGL; 611 | auto var = target->getVariable(name_); 612 | TMP_DEBUGL; 613 | var->set(newVal); 614 | } 615 | 616 | llvm::Value *VariableIndicator::get(LLVMVariableMap *target){ 617 | TMP_DEBUGL; 618 | auto var = target->getVariable(name_); 619 | TMP_DEBUGL; 620 | return var->get(); 621 | } 622 | 623 | StructIndicator::StructIndicator(std::string name, std::string member_name) : VariableIndicator(name){ 624 | member_name_ = member_name; 625 | } 626 | 627 | void StructIndicator::set(LLVMVariableMap *target, llvm::Value *newVal){ 628 | TMP_DEBUGL; 629 | if( member_name_.empty() ){ 630 | ASSERT_FAIL_BLOCK(); 631 | } 632 | TMP_DEBUGL; 633 | TMP_DEBUGS(name_.c_str()); 634 | TMP_DEBUGS(member_name_.c_str()); 635 | auto var = (LLVMStruct *)target->getVariable(name_); 636 | TMP_DEBUGL; 637 | TMP_DEBUGP(newVal); 638 | TMP_DEBUGS(typeid(var).name()); 639 | var->set(member_name_, newVal); 640 | TMP_DEBUGL; 641 | } 642 | 643 | llvm::Value *StructIndicator::get(LLVMVariableMap *target){ 644 | TMP_DEBUGL; 645 | auto var = (LLVMStruct *)target->getVariable(name_); 646 | return var->get(member_name_); 647 | } 648 | 649 | int getFieldDistance(LLVMStructDef::FieldDef fields,std::string field_name){ 650 | for(auto itr = fields.begin(); itr != fields.end(); ++itr) { 651 | if(itr->name == field_name){ 652 | return std::distance(fields.begin(), itr); 653 | } 654 | } 655 | return -1; 656 | } 657 | 658 | ArrayIndicator::ArrayIndicator(std::string name, llvm::Value *index) : VariableIndicator(name){ 659 | index_ = index; 660 | } 661 | 662 | void ArrayIndicator::set(LLVMVariableMap *target, llvm::Value *newVal){ 663 | TMP_DEBUGL; 664 | TMP_DEBUGL; 665 | TMP_DEBUGS(name_.c_str()); 666 | auto var = (LLVMArray *)target->getVariable(name_); 667 | TMP_DEBUGL; 668 | TMP_DEBUGP(newVal); 669 | TMP_DEBUGS(typeid(var).name()); 670 | TMP_DEBUGI(index_); 671 | var->set(index_, newVal); 672 | TMP_DEBUGL; 673 | } 674 | 675 | llvm::Value *ArrayIndicator::get(LLVMVariableMap *target){ 676 | TMP_DEBUGL; 677 | auto var = (LLVMArray *)target->getVariable(name_); 678 | return var->get(index_); 679 | } 680 | -------------------------------------------------------------------------------- /src/mugicha_compiler.cpp: -------------------------------------------------------------------------------- 1 | #include "llvm/Bitcode/ReaderWriter.h" 2 | #include "llvm/IR/BasicBlock.h" 3 | #include "llvm/IR/Constants.h" 4 | #include "llvm/IR/DerivedTypes.h" 5 | #include "llvm/IR/Function.h" 6 | #include "llvm/IR/InstrTypes.h" 7 | #include "llvm/IR/Instruction.h" 8 | #include "llvm/IR/Instructions.h" 9 | #include "llvm/IR/LLVMContext.h" 10 | #include "llvm/IR/Module.h" 11 | #include "llvm/IR/Type.h" 12 | #include "llvm/Support/raw_ostream.h" 13 | 14 | #include "llvm/IR/Module.h" 15 | #include "llvm/IR/TypeBuilder.h" 16 | #include "llvm/IR/Function.h" 17 | #include "llvm/IR/PassManager.h" 18 | #include "llvm/IR/CallingConv.h" 19 | #include "llvm/IR/Verifier.h" 20 | #include "llvm/IR/IRPrintingPasses.h" 21 | #include "llvm/IR/IRBuilder.h" 22 | #include "llvm/IR/DerivedTypes.h" 23 | #include "llvm/IR/DataLayout.h" 24 | 25 | #include "llvm/ADT/STLExtras.h" 26 | 27 | #include "llvm/Bitcode/ReaderWriter.h" 28 | 29 | #include "llvm/Support/raw_ostream.h" 30 | #include "llvm/Support/type_traits.h" 31 | #include "llvm/Support/ToolOutputFile.h" 32 | #include "llvm/Support/FormattedStream.h" 33 | #include "llvm/Support/FileSystem.h" 34 | 35 | #include "llvm/IR/Argument.h" 36 | #include 37 | 38 | 39 | #include "mugicha.h" 40 | #include "stack.h" 41 | #include "support.h" 42 | 43 | #include "func.h" 44 | #include "mugicha_compiler.h" 45 | 46 | #include "llvm_builder.h" 47 | 48 | std::shared_ptr global_scope = std::make_shared(); 49 | ASTNODE *global_ast_rootp; 50 | 51 | llvm::Value *makeMugichaValue(std::shared_ptr scope ,TYPE type, llvm::Value *size){ 52 | auto module = scope->getModuleBuilder(); 53 | 54 | switch(type.kind){ 55 | case KLASS: { 56 | auto klassDefMap = global_scope->getKlassDefMap(); 57 | auto klassDef = klassDefMap->get(type.klass->name); 58 | auto klassId = klassDefMap->getDefId(klassDef->getDefName()); 59 | auto v = (LLVMVariable *)new Klass(module, klassDef, klassId, scope->getStorage()); 60 | return v->get(); 61 | } 62 | case ARRAY: { 63 | llvm::ConstantInt* CI = llvm::dyn_cast(size); 64 | if (!CI) { 65 | ASSERT_FAIL_BLOCK(); 66 | } 67 | auto v = (LLVMVariable *)new LLVMArray(module, type, CI->getSExtValue()); 68 | return v->get(); 69 | } 70 | default: { 71 | ASSERT_FAIL_BLOCK(); 72 | } 73 | } 74 | } 75 | 76 | void makeMugichaVariable(std::shared_ptr scope, std::string name ,TYPE type, llvm::Value *size){ 77 | auto varMap = scope->getVarMap(); 78 | auto storage = scope->getStorage(); 79 | 80 | switch(type.kind){ 81 | case KLASS: { 82 | auto klassDef = global_scope->getKlassDefMap()->get(type.klass->name); 83 | varMap->makeClass(name, klassDef, storage); 84 | break; 85 | } 86 | case ARRAY: { 87 | llvm::ConstantInt* CI = llvm::dyn_cast(size); 88 | if (!CI) { 89 | ASSERT_FAIL_BLOCK(); 90 | } 91 | varMap->makeArray(name, type, CI->getSExtValue()); 92 | break; 93 | } 94 | default: { 95 | varMap->makeVariable(name, type); 96 | break; 97 | } 98 | } 99 | } 100 | 101 | llvm::Type *getLLVMTypeByMugichaType(TYPE type, std::shared_ptr scope) { 102 | switch(type.kind){ 103 | case ANY: 104 | ASSERT_FAIL_BLOCK(); 105 | case INT: 106 | case BOOLTYPE: 107 | return llvm::Type::getInt32Ty(*scope->getContext()); 108 | case DOUBLE: 109 | return llvm::Type::getDoubleTy(*scope->getContext()); 110 | case STRING: 111 | return llvm::Type::getInt8PtrTy(*scope->getContext()); 112 | case KLASS: 113 | return getOpequePtrType(scope->getContext()); 114 | } 115 | } 116 | 117 | MugichaScopeInfo::MugichaScopeInfo() { 118 | context_ = std::make_shared(); 119 | module_ = std::make_shared("mugicha", context_); 120 | struct_def_map_ = std::make_shared(module_); 121 | klass_def_map_ = std::make_shared(module_); 122 | var_map_ = std::make_shared(module_, struct_def_map_, klass_def_map_); 123 | storage_ = std::make_shared(module_); 124 | TMP_DEBUGP(storage_.get()); 125 | if( storage_.get() == nullptr ){ 126 | ASSERT_FAIL_BLOCK(); 127 | } 128 | } 129 | 130 | MugichaScopeInfo::MugichaScopeInfo(std::shared_ptr old_scope) { 131 | context_ = old_scope->context_; 132 | module_ = old_scope->module_; 133 | var_map_ = old_scope->var_map_; 134 | struct_def_map_ = old_scope->struct_def_map_; 135 | klass_def_map_ = old_scope->klass_def_map_; 136 | storage_ = old_scope->storage_; 137 | func_ptr_arr_ = old_scope->func_ptr_arr_; 138 | } 139 | 140 | std::shared_ptr MugichaScopeInfo::getModuleBuilder(){ 141 | return module_; 142 | } 143 | 144 | llvm::Module *MugichaScopeInfo::getModule(){ 145 | return module_->getModule(); 146 | } 147 | 148 | llvm::LLVMContext *MugichaScopeInfo::getContext(){ 149 | return context_.get(); 150 | } 151 | 152 | llvm::IRBuilder<> *MugichaScopeInfo::getBuilder() 153 | { 154 | return module_->getBuilder(); 155 | } 156 | 157 | std::shared_ptr MugichaScopeInfo::makeExprBuilder() 158 | { 159 | TMP_DEBUGL; 160 | std::shared_ptr builder = std::make_shared(this->getFuncBuilder()); 161 | 162 | TMP_DEBUGL; 163 | TMP_DEBUGP(builder.get()); 164 | return builder; 165 | } 166 | 167 | llvm::Function *MugichaScopeInfo::getFunc() 168 | { 169 | llvm::Function *func = this->getBuilder()->GetInsertBlock()->getParent(); 170 | return func; 171 | } 172 | 173 | std::shared_ptr MugichaScopeInfo::getFuncBuilder() 174 | { 175 | std::shared_ptr funcBuilder = std::make_shared(module_, this->getFunc()); 176 | 177 | return funcBuilder; 178 | } 179 | 180 | std::shared_ptr MugichaScopeInfo::getVarMap() 181 | { 182 | return var_map_; 183 | } 184 | 185 | std::shared_ptr MugichaScopeInfo::getStructDefMap() 186 | { 187 | return struct_def_map_; 188 | } 189 | 190 | std::shared_ptr MugichaScopeInfo::getKlassDefMap(){ 191 | return klass_def_map_; 192 | } 193 | 194 | std::shared_ptr MugichaScopeInfo::getStorage(){ 195 | return storage_; 196 | } 197 | 198 | int MugichaScopeInfo::getKlassMax(){ 199 | return klass_def_map_->size(); 200 | } 201 | 202 | int MugichaScopeInfo::getMethodMax(){ 203 | int method_max = 0; 204 | 205 | for (auto& itr:klass_def_map_->getMap()) { 206 | int count = itr.second->getMethodCount(); 207 | if(count > method_max) method_max = count; 208 | } 209 | 210 | return method_max; 211 | } 212 | 213 | int MugichaScopeInfo::getMethodArrayIndex(int klass_id, int method_id){ 214 | return klass_id * 20 + method_id; // TODO : use method max instead of 20 215 | } 216 | 217 | llvm::Value *MugichaScopeInfo::getMethodFromArray(int klass_id, int method_id){ 218 | TMP_DEBUGL; 219 | auto atype = getFuncArrayType(); 220 | TMP_DEBUGL; 221 | auto iBuilder = getBuilder(); 222 | TMP_DEBUGL; 223 | 224 | auto index = getMethodArrayIndex(klass_id, method_id); 225 | TMP_DEBUGL; 226 | TMP_DEBUGP(atype); 227 | TMP_DEBUGP(func_ptr_arr_); 228 | TMP_DEBUGI(index); 229 | auto gep = iBuilder->CreateStructGEP(atype, func_ptr_arr_, index); 230 | TMP_DEBUGL; 231 | auto loadedFunc = iBuilder->CreateLoad(gep); 232 | 233 | return loadedFunc; 234 | } 235 | 236 | llvm::PointerType *MugichaScopeInfo::getOpequePtrType(){ 237 | auto opequeType = llvm::Type::getInt8Ty(*context_); 238 | auto opequePtrType = llvm::PointerType::getUnqual(opequeType); 239 | 240 | return opequePtrType; 241 | } 242 | 243 | llvm::ArrayType *MugichaScopeInfo::getFuncArrayType(){ 244 | auto opequePtrType = getOpequePtrType(); 245 | auto atype = llvm::ArrayType::get(opequePtrType, 20*20);// TODO : use klass nad method max instead of 20 246 | 247 | return atype; 248 | } 249 | 250 | void MugichaScopeInfo::makeFuncPtrArry(){ 251 | auto atype = getFuncArrayType(); 252 | 253 | func_ptr_arr_ = new llvm::GlobalVariable(/*Module=*/*module_->getModule(), 254 | /*Type=*/atype, 255 | /*isConstant=*/false, 256 | /*Linkage=*/llvm::GlobalValue::InternalLinkage, 257 | /*Initializer=*/llvm::ConstantAggregateZero::get(atype)); 258 | 259 | TMP_DEBUGP(func_ptr_arr_); 260 | } 261 | 262 | void MugichaScopeInfo::setFuncPtrArry(){ 263 | auto atype = getFuncArrayType(); 264 | 265 | for (auto& kitr:klass_def_map_->getMap()) { 266 | for (auto& mitr:kitr.second->getMethodMap()) { 267 | auto klass = kitr.second; 268 | auto method = mitr.second; 269 | 270 | int klass_id = klass_def_map_->getDefId(kitr.first); 271 | int method_id = klass->getMethodId(mitr.first); 272 | 273 | auto iBuilder = getBuilder(); 274 | auto gep = iBuilder->CreateStructGEP(atype, func_ptr_arr_, getMethodArrayIndex(klass_id, method_id)); 275 | 276 | auto opequePtrType = getOpequePtrType(); 277 | auto castedMyFunc = iBuilder->CreateBitCast(method->getFunc(), opequePtrType); 278 | auto store = iBuilder->CreateStore(castedMyFunc, gep); 279 | } 280 | } 281 | } 282 | 283 | llvm::GlobalVariable *MugichaScopeInfo::getFuncPtrArry() 284 | { 285 | return func_ptr_arr_; 286 | } 287 | 288 | llvm::Value *exec_def_var_codegen(ASTNODE *ap , std::shared_ptr scope) 289 | { 290 | auto expr = scope->makeExprBuilder(); 291 | 292 | llvm::Value *size; 293 | if(ap->left){ 294 | size = eval_node_codegen(ap->left, scope); 295 | } 296 | makeMugichaVariable(scope, ap->sym->name ,ap->type, size); 297 | 298 | TMP_DEBUGL; 299 | return expr->makeConst(-1); // TODO 300 | } 301 | 302 | std::vector exec_expr_list_vectorgen(ASTNODE *ap, std::shared_ptr scope) 303 | { 304 | std::vector ret; 305 | 306 | TMP_DEBUGL; 307 | 308 | if(ap->op != EXPR_LIST){ 309 | TMP_DEBUGL; 310 | auto r = eval_node_codegen(ap, scope); 311 | TMP_DEBUGL; 312 | ret.push_back(r); 313 | TMP_DEBUGL; 314 | return ret; 315 | } 316 | 317 | TMP_DEBUGL; 318 | 319 | TMP_DEBUGL; 320 | auto lhs = eval_node_codegen(ap->left, scope); 321 | ret.push_back(lhs); 322 | 323 | TMP_DEBUGL; 324 | 325 | if(ap->right->op == EXPR_LIST){ 326 | auto rhs = exec_expr_list_vectorgen(ap->right, scope); 327 | if(!rhs.empty()) ret.insert(ret.end(), rhs.begin(), rhs.end()); 328 | } else { 329 | auto rhs = eval_node_codegen(ap->right, scope); 330 | ret.push_back(rhs); 331 | } 332 | 333 | TMP_DEBUGL; 334 | 335 | return ret; 336 | } 337 | 338 | using ArgTuple = std::tuple; 339 | std::vector exec_args_vectorgen(ASTNODE *ap, std::shared_ptr scope) 340 | { 341 | std::vector ret; 342 | 343 | TMP_DEBUGL; 344 | if(ap->op == DEF_VAR){ 345 | ArgTuple tp = {ap->type, std::string(ap->sym->name)}; 346 | ret.push_back(tp); 347 | TMP_DEBUGS("push_arg"); 348 | TMP_DEBUGS(ap->sym->name); 349 | TMP_DEBUGL; 350 | return ret; 351 | } 352 | 353 | TMP_DEBUGL; 354 | auto lhs = exec_args_vectorgen(ap->left, scope); 355 | TMP_DEBUGL; 356 | ret.insert(ret.end(), lhs.begin(), lhs.end()); 357 | TMP_DEBUGL; 358 | 359 | TMP_DEBUGL; 360 | auto rhs = exec_args_vectorgen(ap->right, scope); 361 | TMP_DEBUGL; 362 | ret.insert(ret.end(), rhs.begin(), rhs.end()); 363 | TMP_DEBUGL; 364 | 365 | return ret; 366 | } 367 | 368 | llvm::Value *exec_set_var_codegen(ASTNODE *ap , std::shared_ptr scope) 369 | { 370 | auto expr = scope->makeExprBuilder(); 371 | TMP_DEBUGL; 372 | 373 | auto ret = eval_node_codegen(ap->left, scope); 374 | TMP_DEBUGL; 375 | 376 | auto target = new VariableIndicator(ap->sym->name); 377 | scope->getVarMap()->set(target ,ret); 378 | TMP_DEBUGL; 379 | return ret; 380 | } 381 | 382 | llvm::Value *exec_get_var_codegen(ASTNODE *ap , std::shared_ptr scope) 383 | { 384 | DEBUGL; 385 | auto expr = scope->makeExprBuilder(); 386 | DEBUGL; 387 | 388 | auto target = new VariableIndicator(ap->sym->name); 389 | TMP_DEBUGS(target); 390 | auto ret = scope->getVarMap()->get(target); 391 | DEBUGL; 392 | 393 | return ret; 394 | } 395 | 396 | llvm::Value *exec_calc_codegen(ASTNODE *ap,OPERATION calc_mode , std::shared_ptr scope) 397 | { 398 | auto expr = scope->makeExprBuilder(); 399 | 400 | // VALUE ret; 401 | // VALUE lhs ,rhs; 402 | // char *s; 403 | // char *rhs_str; 404 | 405 | auto lhs = eval_node_codegen(ap->left ,scope); 406 | auto rhs = eval_node_codegen(ap->right ,scope); 407 | llvm::AddrSpaceCastInst::BinaryOps ops; 408 | 409 | auto type = lhs->getType(); 410 | switch(calc_mode){ 411 | case ADD: 412 | if(type->isIntegerTy()){ 413 | ops = llvm::Instruction::Add; 414 | } else if(type->isDoubleTy()){ 415 | ops = llvm::Instruction::FAdd; 416 | } else if(type->isPointerTy()){ 417 | ASSERT_FAIL_BLOCK(); // TODO String Ready 418 | } else { 419 | ASSERT_FAIL_BLOCK(); 420 | } 421 | break; 422 | case SUB: 423 | if(type->isIntegerTy()){ 424 | ops = llvm::Instruction::Sub; 425 | } else if(type->isDoubleTy()){ 426 | ops = llvm::Instruction::FSub; 427 | } else { 428 | ASSERT_FAIL_BLOCK(); 429 | } 430 | break; 431 | case MUL: 432 | if(type->isIntegerTy()){ 433 | ops = llvm::Instruction::Mul; 434 | } else if(type->isDoubleTy()){ 435 | ops = llvm::Instruction::FMul; 436 | } else { 437 | ASSERT_FAIL_BLOCK(); 438 | } 439 | break; 440 | case DIV: 441 | if(type->isIntegerTy()){ 442 | ops = llvm::Instruction::SDiv; 443 | } else if(type->isDoubleTy()){ 444 | ops = llvm::Instruction::FDiv; 445 | } else { 446 | ASSERT_FAIL_BLOCK(); 447 | } 448 | break; 449 | default: 450 | ASSERT_FAIL_BLOCK(); 451 | } 452 | 453 | return expr->makeCalcOp(ops ,lhs, rhs); 454 | 455 | } 456 | 457 | llvm::Value *exec_print_codegen(ASTNODE *ap, std::shared_ptr scope) 458 | { 459 | auto moduleBuilder = scope->getModuleBuilder(); 460 | auto expr = scope->makeExprBuilder(); 461 | 462 | auto targetValue = eval_node_codegen(ap->left, scope); 463 | std::vector values; 464 | 465 | llvm::Value *formatStr; 466 | auto type = targetValue->getType(); 467 | if( type->isIntegerTy()) { 468 | formatStr = expr->makeConst("value = %d\n"); // TODO type switch 469 | } else if( type->isDoubleTy()) { 470 | formatStr = expr->makeConst("value = %f\n"); // TODO type switch 471 | } else if( type->isPointerTy()) { 472 | formatStr = expr->makeConst("value = %s\n"); // TODO type switch 473 | } 474 | 475 | values.push_back(formatStr); 476 | 477 | // test code start 478 | // auto iBuilder = scope->getBuilder(); 479 | // auto arr = global_scope->getFuncPtrArry(); 480 | // auto intTy = llvm::Type::getInt32Ty(*scope->getContext()); 481 | // auto atype = llvm::ArrayType::get(intTy, 100); 482 | // auto gep = iBuilder->CreateStructGEP(atype, arr, 99); 483 | // auto loadv = iBuilder->CreateLoad(gep); 484 | // values.push_back(loadv); 485 | 486 | // test code end 487 | 488 | values.push_back(targetValue); 489 | 490 | return moduleBuilder->makePrintf(values); 491 | 492 | } 493 | 494 | llvm::Value *exec_def_func_codegen(ASTNODE *ap, std::shared_ptr old_scope) 495 | { 496 | std::shared_ptr new_scope = std::make_shared(old_scope); 497 | 498 | auto context = new_scope->getContext(); 499 | auto module = new_scope->getModule(); 500 | 501 | auto funcInfo = lookup_func(ap->sym); 502 | 503 | std::vector argInfos; 504 | std::vector argTypes; 505 | 506 | auto defArgs = funcInfo->def_args; 507 | if( defArgs ){ 508 | TMP_DEBUGI(defArgs->type.kind); 509 | argInfos = exec_args_vectorgen(defArgs, new_scope); 510 | TMP_DEBUGL; 511 | std::transform(argInfos.begin(), argInfos.end(), std::back_inserter(argTypes), [new_scope](const ArgTuple& e) { 512 | TYPE t = std::get<0>(e); 513 | return getLLVMTypeByMugichaType(t, new_scope); 514 | }); 515 | } 516 | 517 | auto retType = getLLVMTypeByMugichaType(funcInfo->type, new_scope); 518 | auto func_type = 519 | llvm::FunctionType::get(retType, argTypes, false); 520 | 521 | auto func = std::make_shared(new_scope->getModuleBuilder(), func_type, funcInfo->sym->name); 522 | 523 | auto f = lookup_func(ap->sym); 524 | 525 | std::shared_ptr expr = std::make_shared(func); 526 | 527 | auto &argList = func->getFunc()->getArgumentList(); 528 | auto varMap = new_scope->getVarMap(); 529 | 530 | if( defArgs ){ 531 | TMP_DEBUGL; 532 | auto iter = argList.begin(); 533 | TMP_DEBUGL; 534 | TMP_DEBUGL; 535 | 536 | // auto argName =defArgs->sym->name; 537 | 538 | TMP_DEBUGL; 539 | for(auto argInfo : argInfos) { 540 | TMP_DEBUGL; 541 | llvm::Value *argVal = static_cast( &*iter++); 542 | TMP_DEBUGL; 543 | auto argType = std::get<0>(argInfo); 544 | auto argName = std::get<1>(argInfo); 545 | TMP_DEBUGL; 546 | TMP_DEBUGS("set arg"); 547 | TMP_DEBUGS(argName.c_str()); 548 | llvm::Value *size; 549 | if(ap->left){ 550 | size = eval_node_codegen(ap->left, new_scope); 551 | } 552 | makeMugichaVariable(new_scope, argName, argType, size); 553 | TMP_DEBUGL; 554 | auto target = new VariableIndicator(argName); // TODO this memory needs free after process 555 | TMP_DEBUGL; 556 | varMap->set(target, argVal); 557 | TMP_DEBUGL; 558 | } 559 | TMP_DEBUGL; 560 | TMP_DEBUGL; 561 | TMP_DEBUGL; 562 | } 563 | 564 | auto iBuilder = new_scope->getBuilder(); 565 | 566 | TMP_DEBUGL; 567 | auto ret = eval_node_codegen(f->body, new_scope); 568 | TMP_DEBUGL; 569 | 570 | func->makeReturn(ret); 571 | 572 | // make function array after all program is over. 573 | if(!strcmp(ap->sym->name, "main")){ 574 | auto block = func->getBasicBlock(); 575 | auto itr = block->getFirstInsertionPt(); 576 | iBuilder->SetInsertPoint( block,itr ); 577 | global_scope->setFuncPtrArry(); 578 | } 579 | 580 | return ret; 581 | } 582 | 583 | llvm::Value *exec_def_method_codegen(ASTNODE *ap, std::shared_ptr old_scope) 584 | { 585 | std::shared_ptr new_scope = std::make_shared(old_scope); 586 | 587 | auto context = new_scope->getContext(); 588 | auto module = new_scope->getModule(); 589 | 590 | auto funcInfo = lookup_func(ap->sym); 591 | TMP_DEBUGL; 592 | auto kmap = global_scope->getKlassDefMap(); 593 | TMP_DEBUGL; 594 | TMP_DEBUGP(&kmap); 595 | TMP_DEBUGS(ap->reciever_type.klass->name); 596 | auto kd = kmap->get(ap->reciever_type.klass->name); 597 | TMP_DEBUGL; 598 | TMP_DEBUGL; 599 | 600 | std::vector argInfos; 601 | std::vector argTypes; // TODO : now arg is provisional. 602 | 603 | auto defArgs = funcInfo->def_args; 604 | if( defArgs ){ 605 | TMP_DEBUGL; 606 | auto recieverType = getLLVMTypeByMugichaType(ap->reciever_type, new_scope); 607 | TMP_DEBUGL; 608 | argTypes.push_back(recieverType); 609 | TMP_DEBUGL; 610 | argInfos = exec_args_vectorgen(defArgs, new_scope); 611 | std::transform(argInfos.begin(), argInfos.end(), std::back_inserter(argTypes), [new_scope](const ArgTuple& e) { 612 | TYPE t = std::get<0>(e); 613 | return getLLVMTypeByMugichaType(t, new_scope); 614 | }); 615 | } 616 | 617 | auto retType = getLLVMTypeByMugichaType(funcInfo->type, new_scope); 618 | auto func_type = 619 | llvm::FunctionType::get(retType, argTypes, false); 620 | 621 | auto func = std::make_shared(new_scope->getModuleBuilder(), func_type, funcInfo->sym->name); 622 | kd->addMethod(ap->sym->name, func); 623 | 624 | auto f = lookup_func(ap->sym); 625 | 626 | std::shared_ptr expr = std::make_shared(func); 627 | 628 | auto &argList = func->getFunc()->getArgumentList(); 629 | auto varMap = new_scope->getVarMap(); 630 | 631 | if( defArgs ){ 632 | TMP_DEBUGL; 633 | auto iter = argList.begin(); 634 | llvm::Value *recieverVal = static_cast( &*iter); 635 | 636 | auto klassDef = global_scope->getKlassDefMap()->get(ap->reciever_type.klass->name); 637 | varMap->makeClass("this", klassDef, new_scope->getStorage()); 638 | auto reciever = new VariableIndicator("this"); 639 | varMap->set(reciever, recieverVal); 640 | 641 | for(auto argInfo : argInfos) { 642 | TMP_DEBUGL; 643 | llvm::Value *argVal = static_cast( &*++iter); 644 | TMP_DEBUGL; 645 | auto argType = std::get<0>(argInfo); 646 | auto argName = std::get<1>(argInfo); 647 | TMP_DEBUGL; 648 | TMP_DEBUGS("set arg"); 649 | TMP_DEBUGS(argName.c_str()); 650 | llvm::Value *size; 651 | if(ap->left){ 652 | size = eval_node_codegen(ap->left, new_scope); 653 | } 654 | makeMugichaVariable(new_scope, argName, argType, size); 655 | TMP_DEBUGL; 656 | auto target = new VariableIndicator(argName); // TODO this memory needs free after process 657 | TMP_DEBUGL; 658 | varMap->set(target, argVal); 659 | TMP_DEBUGL; 660 | } 661 | } 662 | 663 | TMP_DEBUGL; 664 | auto ret = eval_node_codegen(f->body, new_scope); 665 | TMP_DEBUGL; 666 | 667 | func->makeReturn(ret); 668 | 669 | return ret; 670 | } 671 | 672 | llvm::Value *exec_call_func_codegen(ASTNODE *ap, std::shared_ptr scope) 673 | { 674 | auto module = scope->getModuleBuilder(); 675 | 676 | // TODO argument 677 | // if( ap->set_args != NULL){ 678 | // eval_node(f->def_args); 679 | // eval_node(ap->set_args); 680 | // } 681 | 682 | std::vector argValues; 683 | 684 | auto context = module->getContext(); 685 | auto funcInfo = lookup_func(ap->sym); 686 | 687 | std::vector argInfos; 688 | std::vector argTypes; 689 | 690 | auto defArgs = funcInfo->def_args; 691 | if( defArgs ){ 692 | TMP_DEBUGL; 693 | argInfos = exec_args_vectorgen(defArgs, scope); 694 | std::transform(argInfos.begin(), argInfos.end(), std::back_inserter(argTypes), [scope](const ArgTuple& e) { 695 | TYPE t = std::get<0>(e); 696 | return getLLVMTypeByMugichaType(t, scope); 697 | }); 698 | } 699 | 700 | if( ap->set_args ){ // TODO only single arg. multi arg requre. 701 | TMP_DEBUGL; 702 | argValues = exec_expr_list_vectorgen(ap->set_args, scope); 703 | TMP_DEBUGL; 704 | } 705 | TMP_DEBUGL; 706 | 707 | auto retType = getLLVMTypeByMugichaType(funcInfo->type, scope); 708 | llvm::FunctionType *funcType = 709 | llvm::FunctionType::get(retType, argTypes, true); 710 | llvm::Constant *callFunc = 711 | module->getModule()->getOrInsertFunction(funcInfo->sym->name, funcType); 712 | 713 | auto iBuilder = scope->getBuilder(); 714 | auto ret = iBuilder->CreateCall(callFunc, argValues); 715 | 716 | TMP_DEBUGL; 717 | return ret; 718 | } 719 | 720 | llvm::Value *exec_call_method_codegen(ASTNODE *ap, std::shared_ptr scope) 721 | { 722 | auto module = scope->getModuleBuilder(); 723 | 724 | // TODO argument 725 | // if( ap->set_args != NULL){ 726 | // eval_node(f->def_args); 727 | // eval_node(ap->set_args); 728 | // } 729 | 730 | std::vector argValues; 731 | std::vector argTypes; 732 | 733 | auto context = module->getContext(); 734 | auto funcInfo = lookup_func(ap->sym); 735 | std::vector argInfos; 736 | 737 | auto defArgs = funcInfo->def_args; 738 | if( defArgs ){ 739 | auto recieverVal = scope->getVarMap()->getVariable(ap->reciever->name); 740 | auto recieverType = getLLVMTypeByMugichaType(recieverVal->getType(), scope); 741 | argTypes.push_back(recieverType); 742 | TMP_DEBUGL; 743 | argInfos = exec_args_vectorgen(defArgs, scope); 744 | std::transform(argInfos.begin(), argInfos.end(), std::back_inserter(argTypes), [scope](const ArgTuple& e) { 745 | TYPE t = std::get<0>(e); 746 | return getLLVMTypeByMugichaType(t, scope); 747 | }); 748 | } 749 | 750 | if( ap->set_args ){ // TODO only single arg. multi arg requre. 751 | TMP_DEBUGS(ap->reciever->name); 752 | auto target = new VariableIndicator(ap->reciever->name); 753 | auto recieverVal = scope->getVarMap()->get(target); 754 | argValues.push_back(recieverVal); 755 | TMP_DEBUGL; 756 | auto args = exec_expr_list_vectorgen(ap->set_args, scope); 757 | TMP_DEBUGL; 758 | std::copy(args.begin(),args.end(),std::back_inserter(argValues)); 759 | TMP_DEBUGL; 760 | } 761 | TMP_DEBUGL; 762 | 763 | auto retType = getLLVMTypeByMugichaType(funcInfo->type, scope); 764 | llvm::FunctionType *funcType = 765 | llvm::FunctionType::get(retType, argTypes, true); 766 | 767 | 768 | llvm::Constant *callFunc = 769 | module->getModule()->getOrInsertFunction(funcInfo->sym->name, funcType); 770 | 771 | TMP_DEBUGL; 772 | auto recieverVal = scope->getVarMap()->getVariable(ap->reciever->name); 773 | 774 | TMP_DEBUGL; 775 | auto iBuilder = scope->getBuilder(); 776 | TMP_DEBUGL; 777 | auto kdef_map = global_scope->getKlassDefMap(); 778 | TMP_DEBUGL; 779 | auto klass_def = kdef_map->get(recieverVal->getType().klass->name); 780 | TMP_DEBUGL; 781 | auto klass_id = kdef_map->getDefId(recieverVal->getType().klass->name); 782 | TMP_DEBUGL; 783 | auto method_id = klass_def->getMethodId(ap->sym->name); 784 | TMP_DEBUGL; 785 | auto loadedMethod = global_scope->getMethodFromArray(klass_id, method_id); 786 | TMP_DEBUGL; 787 | 788 | TMP_DEBUGL; 789 | auto funcPtrType = llvm::PointerType::getUnqual(funcType); 790 | auto restoredFunc = iBuilder->CreateBitCast(loadedMethod, funcPtrType); 791 | auto ret = iBuilder->CreateCall(restoredFunc, argValues); 792 | 793 | TMP_DEBUGL; 794 | return ret; 795 | } 796 | 797 | LLVMStructDef::FieldDef getFieldDef(llvm::Module *module, ASTNODE *ap) 798 | { 799 | if(!ap){ 800 | LLVMStructDef::FieldDef f = {}; 801 | 802 | TMP_DEBUGL; 803 | return f; 804 | } 805 | 806 | if(ap->op == DEF_VAR){ 807 | TMP_DEBUGS(ap->sym->name); 808 | LLVMStructDef::FieldDef f = {{ 809 | ap->sym->name, 810 | ap->type 811 | }}; 812 | 813 | return f; 814 | } 815 | TMP_DEBUGL; 816 | LLVMStructDef::FieldDef ret; 817 | 818 | TMP_DEBUGL; 819 | if(ap->super_class){ 820 | TMP_DEBUGL; 821 | ASTNODE *sp = search_ast_by_sym(global_ast_rootp, ap->super_class->name); 822 | TMP_DEBUGL; 823 | if(!sp) ASSERT_FAIL_BLOCK(); 824 | TMP_DEBUGL; 825 | auto s = getFieldDef(module, sp); 826 | TMP_DEBUGL; 827 | if(!s.empty()) ret.insert(ret.end(), s.begin(), s.end()); 828 | TMP_DEBUGL; 829 | } 830 | TMP_DEBUGL; 831 | auto d = getFieldDef(module, ap->def_vars); 832 | ret.insert(ret.end(), d.begin(), d.end()); 833 | auto l = getFieldDef(module, ap->left); 834 | ret.insert(ret.end(), l.begin(), l.end()); 835 | auto r = getFieldDef(module, ap->right); 836 | ret.insert(ret.end(), r.begin(), r.end()); 837 | 838 | return ret; 839 | } 840 | 841 | llvm::Value *exec_def_class_codegen(ASTNODE *ap, std::shared_ptr scope) 842 | { 843 | TMP_DEBUGL; 844 | auto context = scope->getContext(); 845 | TMP_DEBUGL; 846 | auto module = scope->getModule(); 847 | TMP_DEBUGL; 848 | TMP_DEBUGS(ap->sym->name); 849 | 850 | llvm::FunctionType *FT = 851 | llvm::FunctionType::get(llvm::Type::getInt32Ty(*context), /*not vararg*/false); 852 | 853 | TMP_DEBUGL; 854 | //test struct 855 | auto iBuilder = scope->getBuilder(); 856 | TMP_DEBUGL; 857 | auto block = iBuilder->GetInsertBlock(); 858 | TMP_DEBUGL; 859 | 860 | auto intTy = llvm::Type::getInt32Ty(*context); 861 | TMP_DEBUGL; 862 | // LLVMStructDef::FieldDef fields = { 863 | // {"x" ,INT}, 864 | // {"y" ,INT}, 865 | // }; 866 | auto fields = getFieldDef(module, ap); 867 | if(getFieldDistance(fields, KLASS_ID_VAL_NAME) == -1){ 868 | TYPE ty; 869 | ty.kind = INT; 870 | LLVMStructDef::FieldDef id = {{ 871 | KLASS_ID_VAL_NAME, 872 | ty 873 | }}; 874 | fields.insert(fields.begin(), id.begin(), id.end()); 875 | } 876 | TMP_DEBUGL; 877 | 878 | if(fields.empty()){ 879 | ASSERT_FAIL_BLOCK(); 880 | } 881 | 882 | // global_scope->getStructDefMap()->makeStructDef(ap->sym->name, fields); 883 | TMP_DEBUGS(ap->sym->name); 884 | global_scope->getKlassDefMap()->makeKlassDef(ap->sym->name, fields); 885 | 886 | TMP_DEBUGL; 887 | // auto structTy = llvm::StructType::create(fields, "Testx", false); 888 | 889 | // ここから下の宣言がないとStructの宣言も作られないが、この場所で宣言すべきではない 890 | // auto newinst = new llvm::AllocaInst(structTy); 891 | // block->getInstList().push_back(newinst); 892 | 893 | return NULL; 894 | } 895 | 896 | llvm::Value *exec_new_class_codegen(ASTNODE *ap, std::shared_ptr scope) 897 | { 898 | auto expr = scope->makeExprBuilder(); 899 | 900 | llvm::Value *size; 901 | if(ap->left){ 902 | size = eval_node_codegen(ap->left, scope); 903 | } 904 | return makeMugichaValue(scope, ap->type, size); 905 | } 906 | 907 | llvm::Value *exec_set_member_var_codegen(ASTNODE *ap , std::shared_ptr scope) 908 | { 909 | auto expr = scope->makeExprBuilder(); 910 | 911 | auto ret = eval_node_codegen(ap->left, scope); 912 | 913 | auto target = (VariableIndicator *)new StructIndicator(ap->sym->name, ap->member->name); 914 | scope->getVarMap()->set(target, ret); 915 | 916 | return ret; 917 | } 918 | 919 | llvm::Value *exec_get_member_var_codegen(ASTNODE *ap , std::shared_ptr scope) 920 | { 921 | TMP_DEBUGL; 922 | auto expr = scope->makeExprBuilder(); 923 | 924 | if(!ap->sym || !ap->member) ASSERT_FAIL_BLOCK(); 925 | 926 | TMP_DEBUGL; 927 | TMP_DEBUGP(ap->sym); 928 | TMP_DEBUGS(ap->sym->name); 929 | TMP_DEBUGS(ap->member->name); 930 | auto target = (VariableIndicator *)new StructIndicator(ap->sym->name, ap->member->name); 931 | auto ret = scope->getVarMap()->get(target); 932 | 933 | return ret; 934 | } 935 | 936 | llvm::Value *exec_set_array_var_codegen(ASTNODE *ap , std::shared_ptr scope) 937 | { 938 | TMP_DEBUGL; 939 | auto expr = scope->makeExprBuilder(); 940 | 941 | TMP_DEBUGL; 942 | auto ret = eval_node_codegen(ap->left, scope); 943 | 944 | TMP_DEBUGL; 945 | auto index = eval_node_codegen(ap->right, scope); 946 | auto target = (VariableIndicator *)new ArrayIndicator(ap->sym->name, index); 947 | TMP_DEBUGL; 948 | scope->getVarMap()->set(target, ret); 949 | 950 | TMP_DEBUGL; 951 | return ret; 952 | } 953 | 954 | llvm::Value *exec_get_array_var_codegen(ASTNODE *ap , std::shared_ptr scope) 955 | { 956 | TMP_DEBUGL; 957 | auto expr = scope->makeExprBuilder(); 958 | 959 | if(!ap->sym) ASSERT_FAIL_BLOCK(); 960 | 961 | TMP_DEBUGL; 962 | TMP_DEBUGP(ap->sym); 963 | TMP_DEBUGS(ap->sym->name); 964 | auto index = eval_node_codegen(ap->left, scope); 965 | auto target = (VariableIndicator *)new ArrayIndicator(ap->sym->name, index); 966 | TMP_DEBUGL; 967 | auto ret = scope->getVarMap()->get(target); 968 | TMP_DEBUGL; 969 | 970 | return ret; 971 | } 972 | 973 | llvm::Value *exec_seq_codegen(ASTNODE *ap, std::shared_ptr scope) 974 | { 975 | TMP_DEBUGL; 976 | auto lhs = eval_node_codegen(ap->left, scope); 977 | TMP_DEBUGL; 978 | auto rhs = eval_node_codegen(ap->right, scope); 979 | TMP_DEBUGL; 980 | 981 | return rhs; 982 | } 983 | 984 | llvm::Value *exec_if_codegen(ASTNODE *ap, std::shared_ptr scope) 985 | { 986 | auto module = scope->getModuleBuilder(); 987 | auto context = module->getContext(); 988 | auto iBuilder = module->getBuilder(); 989 | 990 | auto builder2 = scope->makeExprBuilder(); 991 | 992 | // llvm::Value *v1 = builder2->makeConst(1); 993 | // llvm::Value *v2 = builder2->makeConst(1); 994 | // 995 | // llvm::Value *v3 = iBuilder->CreateAlloca(llvm::Type::getInt32Ty(*context), 0, "x"); 996 | // iBuilder->CreateStore(v2, v3); 997 | // v3 = iBuilder->CreateLoad(v3); 998 | // // llvm::Instruction *Add1 = builder2->makeCalcOp(llvm::Instruction::Add, v1,v3); 999 | 1000 | 1001 | // llvm::Value *CondCheck = iBuilder->CreateICmpEQ( 1002 | // Add1, builder2->makeConst(3), "ifcond"); 1003 | 1004 | auto CondV = eval_node_codegen(ap->condition, scope); 1005 | 1006 | auto TheFunction = iBuilder->GetInsertBlock()->getParent(); 1007 | auto ThenBB = llvm::BasicBlock::Create(*context, "then", TheFunction); 1008 | auto ElseBB = llvm::BasicBlock::Create(*context, "else"); 1009 | auto MergeBB = llvm::BasicBlock::Create(*context, "ifcont"); 1010 | 1011 | 1012 | iBuilder->CreateCondBr(CondV, ThenBB, ElseBB); 1013 | 1014 | iBuilder->SetInsertPoint(ThenBB); 1015 | 1016 | auto ThenV = eval_node_codegen(ap->left, scope); 1017 | 1018 | iBuilder->CreateBr(MergeBB); 1019 | 1020 | ThenBB = iBuilder->GetInsertBlock(); 1021 | 1022 | TheFunction->getBasicBlockList().push_back(ElseBB); 1023 | iBuilder->SetInsertPoint(ElseBB); 1024 | 1025 | auto ElseV= eval_node_codegen(ap->right, scope); 1026 | 1027 | iBuilder->CreateBr(MergeBB); 1028 | 1029 | ElseBB = iBuilder->GetInsertBlock(); 1030 | 1031 | TheFunction->getBasicBlockList().push_back(MergeBB); 1032 | iBuilder->SetInsertPoint(MergeBB); 1033 | llvm::PHINode *PN = iBuilder->CreatePHI(llvm::Type::getInt32Ty(*context), 2, "iftmp"); 1034 | 1035 | 1036 | PN->addIncoming(ThenV, ThenBB); 1037 | PN->addIncoming(ElseV, ElseBB); 1038 | 1039 | return PN; 1040 | } 1041 | 1042 | llvm::Value *exec_while_codegen(ASTNODE *ap, std::shared_ptr scope) 1043 | { 1044 | auto module = scope->getModuleBuilder(); 1045 | llvm::LLVMContext *context = module->getContext(); 1046 | llvm::IRBuilder<> *iBuilder = module->getBuilder(); 1047 | 1048 | std::shared_ptr builder2 = scope->makeExprBuilder(); 1049 | 1050 | llvm::Function *TheFunction = iBuilder->GetInsertBlock()->getParent(); 1051 | llvm::BasicBlock *CondBB = llvm::BasicBlock::Create(*context, "cond", TheFunction); 1052 | llvm::BasicBlock *LoopBB = llvm::BasicBlock::Create(*context, "loop", TheFunction); 1053 | llvm::BasicBlock *AfterBB = llvm::BasicBlock::Create(*context, "afterloop", TheFunction); 1054 | // BasicBlock *LoopBodyBB = BasicBlock::Create(*context, "loopbody", TheFunction); 1055 | 1056 | iBuilder->CreateBr(CondBB); 1057 | iBuilder->SetInsertPoint(CondBB); 1058 | 1059 | llvm::Value *CondCheck = eval_node_codegen(ap->condition, scope); 1060 | llvm::Value *CondV = iBuilder->CreateICmpEQ( 1061 | CondCheck, llvm::ConstantInt::getTrue(*context), "loopcond"); 1062 | iBuilder->CreateCondBr(CondV, LoopBB, AfterBB); 1063 | 1064 | iBuilder->SetInsertPoint(LoopBB); 1065 | 1066 | llvm::Value *LoopV = eval_node_codegen(ap->left, scope); 1067 | iBuilder->CreateBr(CondBB); 1068 | 1069 | iBuilder->SetInsertPoint(AfterBB); 1070 | 1071 | 1072 | return LoopV; 1073 | } 1074 | 1075 | llvm::Value *exec_cmp_codegen(ASTNODE *ap ,OPERATION comp_mode, std::shared_ptr scope) 1076 | { 1077 | auto lhs = eval_node_codegen(ap->left ,scope); 1078 | auto rhs = eval_node_codegen(ap->right ,scope); 1079 | 1080 | llvm::Value *ret; 1081 | auto iBuilder = scope->getBuilder(); 1082 | 1083 | switch(comp_mode){ 1084 | case CMP_EQ: 1085 | ret = iBuilder->CreateICmpEQ(lhs, rhs, "cond"); 1086 | break; 1087 | case CMP_NOTEQ: 1088 | ret = iBuilder->CreateICmpNE(lhs, rhs, "cond"); 1089 | break; 1090 | case CMP_GREATER: 1091 | ret = iBuilder->CreateICmpSGT(lhs, rhs, "cond"); 1092 | break; 1093 | case CMP_SMALLER: 1094 | ret = iBuilder->CreateICmpSLT(lhs, rhs, "cond"); 1095 | break; 1096 | case CMP_GREATEREQ: 1097 | ret = iBuilder->CreateICmpSGE(lhs, rhs, "cond"); 1098 | break; 1099 | case CMP_SMALLEREQ: 1100 | ret = iBuilder->CreateICmpSLE(lhs, rhs, "cond"); 1101 | break; 1102 | default: 1103 | ASSERT_FAIL("invalid operation."); 1104 | } 1105 | 1106 | return ret; 1107 | } 1108 | 1109 | llvm::Value *eval_node_op_codegen(ASTNODE *ap, std::shared_ptr scope) 1110 | { 1111 | DEBUGS(get_op_description(ap->op)); 1112 | switch(ap->op){ 1113 | case ADD: 1114 | case SUB: 1115 | case MUL: 1116 | case DIV: 1117 | return exec_calc_codegen(ap ,ap->op, scope); 1118 | case SEQ: 1119 | return exec_seq_codegen(ap, scope); 1120 | case EXPR_LIST: 1121 | case NONE: 1122 | case VALUEDATA: 1123 | ASSERT_FAIL("this block expect never call."); 1124 | case CMP_EQ: 1125 | case CMP_NOTEQ: 1126 | case CMP_GREATER: 1127 | case CMP_SMALLER: 1128 | case CMP_GREATEREQ: 1129 | case CMP_SMALLEREQ: 1130 | return exec_cmp_codegen(ap, ap->op, scope); 1131 | case PRINTDATA: 1132 | return exec_print_codegen(ap, scope); 1133 | case DEF_VAR: 1134 | return exec_def_var_codegen(ap, scope); 1135 | case SET_VAR: 1136 | return exec_set_var_codegen(ap, scope); 1137 | case GET_VAR: 1138 | return exec_get_var_codegen(ap, scope); 1139 | case DEF_FUNC: 1140 | return exec_def_func_codegen(ap ,scope); 1141 | case DEF_METHOD: 1142 | return exec_def_method_codegen(ap ,scope); 1143 | case CALL_FUNC: 1144 | return exec_call_func_codegen(ap, scope); 1145 | case CALL_METHOD: 1146 | return exec_call_method_codegen(ap, scope); 1147 | case DEF_CLASS: 1148 | return exec_def_class_codegen(ap ,scope); 1149 | case NEW_CLASS: 1150 | return exec_new_class_codegen(ap ,scope); 1151 | case SET_MEMBER_VAR: 1152 | return exec_set_member_var_codegen(ap, scope); 1153 | case GET_MEMBER_VAR: 1154 | return exec_get_member_var_codegen(ap, scope); 1155 | case SET_ARRAY_VAR: 1156 | return exec_set_array_var_codegen(ap, scope); 1157 | case GET_ARRAY_VAR: 1158 | return exec_get_array_var_codegen(ap, scope); 1159 | case IF_STMT: 1160 | return exec_if_codegen(ap, scope); 1161 | case WHILE_STMT: 1162 | return exec_while_codegen(ap, scope); 1163 | } 1164 | ASSERT_FAIL("this block expect never call."); 1165 | } 1166 | 1167 | llvm::Value *eval_node_value_codegen(ASTNODE *ap, std::shared_ptr scope ) 1168 | { 1169 | auto expr = scope->makeExprBuilder(); 1170 | 1171 | switch(ap->val.type.kind){ 1172 | case INT: 1173 | return expr->makeConst(ap->val.val.i); 1174 | break; 1175 | case DOUBLE: 1176 | return expr->makeConst(ap->val.val.d); 1177 | break; 1178 | case BOOLTYPE: 1179 | return expr->makeConst(ap->val.val.b); 1180 | break; 1181 | case STRING: 1182 | return expr->makeConst(ap->val.val.s); 1183 | break; 1184 | default: 1185 | ASSERT_FAIL_BLOCK(); 1186 | } 1187 | } 1188 | 1189 | llvm::Value *eval_node_codegen(ASTNODE *ap, std::shared_ptr scope) 1190 | { 1191 | if(ap->op == VALUEDATA ) return eval_node_value_codegen(ap, scope); 1192 | 1193 | return eval_node_op_codegen(ap, scope); 1194 | } 1195 | 1196 | void do_compile(ASTNODE *ast_rootp) 1197 | { 1198 | DEBUGL; 1199 | std::shared_ptr scope = std::make_shared(global_scope); 1200 | 1201 | global_ast_rootp = ast_rootp; 1202 | DEBUGL; 1203 | global_scope->makeFuncPtrArry(); 1204 | 1205 | eval_node_codegen(ast_rootp, scope); 1206 | 1207 | 1208 | // 1209 | DEBUGL; 1210 | WriteBitcodeToFile(scope->getModule(), llvm::outs()); 1211 | } 1212 | 1213 | extern "C" void mugicha_compile(ASTNODE *rootp) 1214 | { 1215 | print_ast(0, rootp); 1216 | 1217 | do_compile(rootp); 1218 | 1219 | DEBUGS("compile complete."); 1220 | } 1221 | -------------------------------------------------------------------------------- /src/y.output: -------------------------------------------------------------------------------- 1 | Terminals which are not used 2 | 3 | '\n' 4 | '!' 5 | '"' 6 | 7 | 8 | Rules never reduced 9 | 10 | 69 primary_string: NAME 11 | 12 | 13 | State 5 conflicts: 23 reduce/reduce 14 | State 21 conflicts: 4 shift/reduce 15 | State 22 conflicts: 4 shift/reduce 16 | State 23 conflicts: 1 shift/reduce 17 | State 40 conflicts: 6 reduce/reduce 18 | State 45 conflicts: 10 shift/reduce 19 | State 74 conflicts: 23 reduce/reduce 20 | State 77 conflicts: 1 shift/reduce 21 | State 97 conflicts: 23 reduce/reduce 22 | 23 | 24 | Grammar 25 | 26 | 0 $accept: prog $end 27 | 28 | 1 prog: /* empty */ 29 | 2 | stmt 30 | 31 | 3 stmt: expr 32 | 4 | def_var 33 | 5 | set_var 34 | 6 | def_func 35 | 7 | if_stmt 36 | 8 | while_stmt 37 | 9 | stmt stmt 38 | 39 | 10 def_func: FUNCTION NAME '(' def_var ')' TYPE_LITERAL '{' stmt '}' 40 | 11 | FUNCTION NAME '(' ')' TYPE_LITERAL '{' stmt '}' 41 | 42 | 12 def_var: VAR NAME TYPE_LITERAL 43 | 44 | 13 set_var: NAME '=' expr 45 | 46 | 14 if_stmt: IF expr_bool '{' stmt '}' ELSE '{' stmt '}' 47 | 48 | 15 while_stmt: WHILE expr_bool '{' stmt '}' 49 | 50 | 16 expr: expr_int 51 | 17 | expr_print 52 | 18 | expr_bool 53 | 19 | expr_double 54 | 20 | expr_string 55 | 21 | call_func 56 | 22 | expr '+' expr 57 | 23 | expr '-' expr 58 | 24 | expr '*' expr 59 | 25 | expr '/' expr 60 | 61 | 26 call_func: NAME '(' set_var ')' 62 | 27 | NAME '(' ')' 63 | 64 | 28 expr_print: PRINT '(' stmt ')' 65 | 29 | PRINT '(' expr ')' 66 | 67 | 30 expr_int: expr_int '+' expr_int 68 | 31 | expr_int '-' expr_int 69 | 32 | expr_int '*' expr_int 70 | 33 | expr_int '/' expr_int 71 | 34 | primary_int 72 | 73 | 35 expr_double: expr_double '+' expr_double 74 | 36 | expr_double '-' expr_double 75 | 37 | expr_double '*' expr_double 76 | 38 | expr_double '/' expr_double 77 | 39 | primary_double 78 | 79 | 40 expr_string: expr_string '+' expr_string 80 | 41 | expr_string '+' expr_int 81 | 42 | expr_string '+' expr_double 82 | 43 | expr_string '+' expr_bool 83 | 44 | primary_string 84 | 85 | 45 expr_bool: primary_bool 86 | 46 | expr_cmp_eq 87 | 47 | expr_cmp_noteq 88 | 48 | expr_cmp_greater 89 | 49 | expr_cmp_smaller 90 | 50 | expr_cmp_greaterequal 91 | 51 | expr_cmp_smallerequal 92 | 93 | 52 expr_cmp_eq: primary_int EQUAL primary_int 94 | 53 | primary_bool EQUAL primary_bool 95 | 96 | 54 expr_cmp_noteq: primary_int NOTEQUAL primary_int 97 | 55 | primary_bool NOTEQUAL primary_bool 98 | 99 | 56 expr_cmp_greater: primary_int '>' primary_int 100 | 57 | primary_bool '>' primary_bool 101 | 102 | 58 expr_cmp_smaller: primary_int '<' primary_int 103 | 59 | primary_bool '<' primary_bool 104 | 105 | 60 expr_cmp_greaterequal: primary_int GREATEREQUAL primary_int 106 | 61 | primary_bool GREATEREQUAL primary_bool 107 | 108 | 62 expr_cmp_smallerequal: primary_int SMALLEREQUAL primary_int 109 | 63 | primary_bool SMALLEREQUAL primary_bool 110 | 111 | 64 primary_int: INT_LITERAL 112 | 65 | NAME 113 | 114 | 66 primary_double: DOUBLE_LITERAL 115 | 67 | NAME 116 | 117 | 68 primary_string: STRING_LITERAL 118 | 69 | NAME 119 | 120 | 70 primary_bool: BOOL_LITERAL 121 | 71 | NAME 122 | 123 | 124 | Terminals, with rules where they appear 125 | 126 | $end (0) 0 127 | '\n' (10) 128 | '!' (33) 129 | '"' (34) 130 | '(' (40) 10 11 26 27 28 29 131 | ')' (41) 10 11 26 27 28 29 132 | '*' (42) 24 32 37 133 | '+' (43) 22 30 35 40 41 42 43 134 | '-' (45) 23 31 36 135 | '/' (47) 25 33 38 136 | '<' (60) 58 59 137 | '=' (61) 13 138 | '>' (62) 56 57 139 | '{' (123) 10 11 14 15 140 | '}' (125) 10 11 14 15 141 | error (256) 142 | DOUBLE_LITERAL (258) 66 143 | INT_LITERAL (259) 64 144 | BOOL_LITERAL (260) 70 145 | STRING_LITERAL (261) 68 146 | NAME (262) 10 11 12 13 26 27 65 67 69 71 147 | TYPE_LITERAL (263) 10 11 12 148 | EQUAL (264) 52 53 149 | PRINT (265) 28 29 150 | VAR (266) 12 151 | FUNCTION (267) 10 11 152 | NOTEQUAL (268) 54 55 153 | SMALLEREQUAL (269) 62 63 154 | GREATEREQUAL (270) 60 61 155 | IF (271) 14 156 | ELSE (272) 14 157 | WHILE (273) 15 158 | 159 | 160 | Nonterminals, with rules where they appear 161 | 162 | $accept (33) 163 | on left: 0 164 | prog (34) 165 | on left: 1 2, on right: 0 166 | stmt (35) 167 | on left: 3 4 5 6 7 8 9, on right: 2 9 10 11 14 15 28 168 | def_func (36) 169 | on left: 10 11, on right: 6 170 | def_var (37) 171 | on left: 12, on right: 4 10 172 | set_var (38) 173 | on left: 13, on right: 5 26 174 | if_stmt (39) 175 | on left: 14, on right: 7 176 | while_stmt (40) 177 | on left: 15, on right: 8 178 | expr (41) 179 | on left: 16 17 18 19 20 21 22 23 24 25, on right: 3 13 22 23 24 180 | 25 29 181 | call_func (42) 182 | on left: 26 27, on right: 21 183 | expr_print (43) 184 | on left: 28 29, on right: 17 185 | expr_int (44) 186 | on left: 30 31 32 33 34, on right: 16 30 31 32 33 41 187 | expr_double (45) 188 | on left: 35 36 37 38 39, on right: 19 35 36 37 38 42 189 | expr_string (46) 190 | on left: 40 41 42 43 44, on right: 20 40 41 42 43 191 | expr_bool (47) 192 | on left: 45 46 47 48 49 50 51, on right: 14 15 18 43 193 | expr_cmp_eq (48) 194 | on left: 52 53, on right: 46 195 | expr_cmp_noteq (49) 196 | on left: 54 55, on right: 47 197 | expr_cmp_greater (50) 198 | on left: 56 57, on right: 48 199 | expr_cmp_smaller (51) 200 | on left: 58 59, on right: 49 201 | expr_cmp_greaterequal (52) 202 | on left: 60 61, on right: 50 203 | expr_cmp_smallerequal (53) 204 | on left: 62 63, on right: 51 205 | primary_int (54) 206 | on left: 64 65, on right: 34 52 54 56 58 60 62 207 | primary_double (55) 208 | on left: 66 67, on right: 39 209 | primary_string (56) 210 | on left: 68 69, on right: 44 211 | primary_bool (57) 212 | on left: 70 71, on right: 45 53 55 57 59 61 63 213 | 214 | 215 | state 0 216 | 217 | 0 $accept: . prog $end 218 | 219 | DOUBLE_LITERAL shift, and go to state 1 220 | INT_LITERAL shift, and go to state 2 221 | BOOL_LITERAL shift, and go to state 3 222 | STRING_LITERAL shift, and go to state 4 223 | NAME shift, and go to state 5 224 | PRINT shift, and go to state 6 225 | VAR shift, and go to state 7 226 | FUNCTION shift, and go to state 8 227 | IF shift, and go to state 9 228 | WHILE shift, and go to state 10 229 | 230 | $default reduce using rule 1 (prog) 231 | 232 | prog go to state 11 233 | stmt go to state 12 234 | def_func go to state 13 235 | def_var go to state 14 236 | set_var go to state 15 237 | if_stmt go to state 16 238 | while_stmt go to state 17 239 | expr go to state 18 240 | call_func go to state 19 241 | expr_print go to state 20 242 | expr_int go to state 21 243 | expr_double go to state 22 244 | expr_string go to state 23 245 | expr_bool go to state 24 246 | expr_cmp_eq go to state 25 247 | expr_cmp_noteq go to state 26 248 | expr_cmp_greater go to state 27 249 | expr_cmp_smaller go to state 28 250 | expr_cmp_greaterequal go to state 29 251 | expr_cmp_smallerequal go to state 30 252 | primary_int go to state 31 253 | primary_double go to state 32 254 | primary_string go to state 33 255 | primary_bool go to state 34 256 | 257 | 258 | state 1 259 | 260 | 66 primary_double: DOUBLE_LITERAL . 261 | 262 | $default reduce using rule 66 (primary_double) 263 | 264 | 265 | state 2 266 | 267 | 64 primary_int: INT_LITERAL . 268 | 269 | $default reduce using rule 64 (primary_int) 270 | 271 | 272 | state 3 273 | 274 | 70 primary_bool: BOOL_LITERAL . 275 | 276 | $default reduce using rule 70 (primary_bool) 277 | 278 | 279 | state 4 280 | 281 | 68 primary_string: STRING_LITERAL . 282 | 283 | $default reduce using rule 68 (primary_string) 284 | 285 | 286 | state 5 287 | 288 | 13 set_var: NAME . '=' expr 289 | 26 call_func: NAME . '(' set_var ')' 290 | 27 | NAME . '(' ')' 291 | 65 primary_int: NAME . 292 | 67 primary_double: NAME . 293 | 69 primary_string: NAME . 294 | 71 primary_bool: NAME . 295 | 296 | '(' shift, and go to state 35 297 | '=' shift, and go to state 36 298 | 299 | $end reduce using rule 65 (primary_int) 300 | $end [reduce using rule 67 (primary_double)] 301 | $end [reduce using rule 69 (primary_string)] 302 | $end [reduce using rule 71 (primary_bool)] 303 | DOUBLE_LITERAL reduce using rule 65 (primary_int) 304 | DOUBLE_LITERAL [reduce using rule 67 (primary_double)] 305 | DOUBLE_LITERAL [reduce using rule 69 (primary_string)] 306 | DOUBLE_LITERAL [reduce using rule 71 (primary_bool)] 307 | INT_LITERAL reduce using rule 65 (primary_int) 308 | INT_LITERAL [reduce using rule 67 (primary_double)] 309 | INT_LITERAL [reduce using rule 69 (primary_string)] 310 | INT_LITERAL [reduce using rule 71 (primary_bool)] 311 | BOOL_LITERAL reduce using rule 65 (primary_int) 312 | BOOL_LITERAL [reduce using rule 67 (primary_double)] 313 | BOOL_LITERAL [reduce using rule 69 (primary_string)] 314 | BOOL_LITERAL [reduce using rule 71 (primary_bool)] 315 | STRING_LITERAL reduce using rule 65 (primary_int) 316 | STRING_LITERAL [reduce using rule 67 (primary_double)] 317 | STRING_LITERAL [reduce using rule 69 (primary_string)] 318 | STRING_LITERAL [reduce using rule 71 (primary_bool)] 319 | NAME reduce using rule 65 (primary_int) 320 | NAME [reduce using rule 67 (primary_double)] 321 | NAME [reduce using rule 69 (primary_string)] 322 | NAME [reduce using rule 71 (primary_bool)] 323 | '+' reduce using rule 65 (primary_int) 324 | '+' [reduce using rule 67 (primary_double)] 325 | '+' [reduce using rule 69 (primary_string)] 326 | '+' [reduce using rule 71 (primary_bool)] 327 | '-' reduce using rule 65 (primary_int) 328 | '-' [reduce using rule 67 (primary_double)] 329 | '-' [reduce using rule 69 (primary_string)] 330 | '-' [reduce using rule 71 (primary_bool)] 331 | '*' reduce using rule 65 (primary_int) 332 | '*' [reduce using rule 67 (primary_double)] 333 | '*' [reduce using rule 69 (primary_string)] 334 | '*' [reduce using rule 71 (primary_bool)] 335 | '/' reduce using rule 65 (primary_int) 336 | '/' [reduce using rule 67 (primary_double)] 337 | '/' [reduce using rule 69 (primary_string)] 338 | '/' [reduce using rule 71 (primary_bool)] 339 | ')' reduce using rule 65 (primary_int) 340 | ')' [reduce using rule 67 (primary_double)] 341 | ')' [reduce using rule 69 (primary_string)] 342 | ')' [reduce using rule 71 (primary_bool)] 343 | EQUAL reduce using rule 65 (primary_int) 344 | EQUAL [reduce using rule 71 (primary_bool)] 345 | PRINT reduce using rule 65 (primary_int) 346 | PRINT [reduce using rule 67 (primary_double)] 347 | PRINT [reduce using rule 69 (primary_string)] 348 | PRINT [reduce using rule 71 (primary_bool)] 349 | VAR reduce using rule 65 (primary_int) 350 | VAR [reduce using rule 67 (primary_double)] 351 | VAR [reduce using rule 69 (primary_string)] 352 | VAR [reduce using rule 71 (primary_bool)] 353 | FUNCTION reduce using rule 65 (primary_int) 354 | FUNCTION [reduce using rule 67 (primary_double)] 355 | FUNCTION [reduce using rule 69 (primary_string)] 356 | FUNCTION [reduce using rule 71 (primary_bool)] 357 | NOTEQUAL reduce using rule 65 (primary_int) 358 | NOTEQUAL [reduce using rule 71 (primary_bool)] 359 | '<' reduce using rule 65 (primary_int) 360 | '<' [reduce using rule 71 (primary_bool)] 361 | '>' reduce using rule 65 (primary_int) 362 | '>' [reduce using rule 71 (primary_bool)] 363 | SMALLEREQUAL reduce using rule 65 (primary_int) 364 | SMALLEREQUAL [reduce using rule 71 (primary_bool)] 365 | GREATEREQUAL reduce using rule 65 (primary_int) 366 | GREATEREQUAL [reduce using rule 71 (primary_bool)] 367 | IF reduce using rule 65 (primary_int) 368 | IF [reduce using rule 67 (primary_double)] 369 | IF [reduce using rule 69 (primary_string)] 370 | IF [reduce using rule 71 (primary_bool)] 371 | WHILE reduce using rule 65 (primary_int) 372 | WHILE [reduce using rule 67 (primary_double)] 373 | WHILE [reduce using rule 69 (primary_string)] 374 | WHILE [reduce using rule 71 (primary_bool)] 375 | '}' reduce using rule 65 (primary_int) 376 | '}' [reduce using rule 67 (primary_double)] 377 | '}' [reduce using rule 69 (primary_string)] 378 | '}' [reduce using rule 71 (primary_bool)] 379 | $default reduce using rule 65 (primary_int) 380 | 381 | 382 | state 6 383 | 384 | 28 expr_print: PRINT . '(' stmt ')' 385 | 29 | PRINT . '(' expr ')' 386 | 387 | '(' shift, and go to state 37 388 | 389 | 390 | state 7 391 | 392 | 12 def_var: VAR . NAME TYPE_LITERAL 393 | 394 | NAME shift, and go to state 38 395 | 396 | 397 | state 8 398 | 399 | 10 def_func: FUNCTION . NAME '(' def_var ')' TYPE_LITERAL '{' stmt '}' 400 | 11 | FUNCTION . NAME '(' ')' TYPE_LITERAL '{' stmt '}' 401 | 402 | NAME shift, and go to state 39 403 | 404 | 405 | state 9 406 | 407 | 14 if_stmt: IF . expr_bool '{' stmt '}' ELSE '{' stmt '}' 408 | 409 | INT_LITERAL shift, and go to state 2 410 | BOOL_LITERAL shift, and go to state 3 411 | NAME shift, and go to state 40 412 | 413 | expr_bool go to state 41 414 | expr_cmp_eq go to state 25 415 | expr_cmp_noteq go to state 26 416 | expr_cmp_greater go to state 27 417 | expr_cmp_smaller go to state 28 418 | expr_cmp_greaterequal go to state 29 419 | expr_cmp_smallerequal go to state 30 420 | primary_int go to state 42 421 | primary_bool go to state 34 422 | 423 | 424 | state 10 425 | 426 | 15 while_stmt: WHILE . expr_bool '{' stmt '}' 427 | 428 | INT_LITERAL shift, and go to state 2 429 | BOOL_LITERAL shift, and go to state 3 430 | NAME shift, and go to state 40 431 | 432 | expr_bool go to state 43 433 | expr_cmp_eq go to state 25 434 | expr_cmp_noteq go to state 26 435 | expr_cmp_greater go to state 27 436 | expr_cmp_smaller go to state 28 437 | expr_cmp_greaterequal go to state 29 438 | expr_cmp_smallerequal go to state 30 439 | primary_int go to state 42 440 | primary_bool go to state 34 441 | 442 | 443 | state 11 444 | 445 | 0 $accept: prog . $end 446 | 447 | $end shift, and go to state 44 448 | 449 | 450 | state 12 451 | 452 | 2 prog: stmt . 453 | 9 stmt: stmt . stmt 454 | 455 | DOUBLE_LITERAL shift, and go to state 1 456 | INT_LITERAL shift, and go to state 2 457 | BOOL_LITERAL shift, and go to state 3 458 | STRING_LITERAL shift, and go to state 4 459 | NAME shift, and go to state 5 460 | PRINT shift, and go to state 6 461 | VAR shift, and go to state 7 462 | FUNCTION shift, and go to state 8 463 | IF shift, and go to state 9 464 | WHILE shift, and go to state 10 465 | 466 | $default reduce using rule 2 (prog) 467 | 468 | stmt go to state 45 469 | def_func go to state 13 470 | def_var go to state 14 471 | set_var go to state 15 472 | if_stmt go to state 16 473 | while_stmt go to state 17 474 | expr go to state 18 475 | call_func go to state 19 476 | expr_print go to state 20 477 | expr_int go to state 21 478 | expr_double go to state 22 479 | expr_string go to state 23 480 | expr_bool go to state 24 481 | expr_cmp_eq go to state 25 482 | expr_cmp_noteq go to state 26 483 | expr_cmp_greater go to state 27 484 | expr_cmp_smaller go to state 28 485 | expr_cmp_greaterequal go to state 29 486 | expr_cmp_smallerequal go to state 30 487 | primary_int go to state 31 488 | primary_double go to state 32 489 | primary_string go to state 33 490 | primary_bool go to state 34 491 | 492 | 493 | state 13 494 | 495 | 6 stmt: def_func . 496 | 497 | $default reduce using rule 6 (stmt) 498 | 499 | 500 | state 14 501 | 502 | 4 stmt: def_var . 503 | 504 | $default reduce using rule 4 (stmt) 505 | 506 | 507 | state 15 508 | 509 | 5 stmt: set_var . 510 | 511 | $default reduce using rule 5 (stmt) 512 | 513 | 514 | state 16 515 | 516 | 7 stmt: if_stmt . 517 | 518 | $default reduce using rule 7 (stmt) 519 | 520 | 521 | state 17 522 | 523 | 8 stmt: while_stmt . 524 | 525 | $default reduce using rule 8 (stmt) 526 | 527 | 528 | state 18 529 | 530 | 3 stmt: expr . 531 | 22 expr: expr . '+' expr 532 | 23 | expr . '-' expr 533 | 24 | expr . '*' expr 534 | 25 | expr . '/' expr 535 | 536 | '+' shift, and go to state 46 537 | '-' shift, and go to state 47 538 | '*' shift, and go to state 48 539 | '/' shift, and go to state 49 540 | 541 | $default reduce using rule 3 (stmt) 542 | 543 | 544 | state 19 545 | 546 | 21 expr: call_func . 547 | 548 | $default reduce using rule 21 (expr) 549 | 550 | 551 | state 20 552 | 553 | 17 expr: expr_print . 554 | 555 | $default reduce using rule 17 (expr) 556 | 557 | 558 | state 21 559 | 560 | 16 expr: expr_int . 561 | 30 expr_int: expr_int . '+' expr_int 562 | 31 | expr_int . '-' expr_int 563 | 32 | expr_int . '*' expr_int 564 | 33 | expr_int . '/' expr_int 565 | 566 | '+' shift, and go to state 50 567 | '-' shift, and go to state 51 568 | '*' shift, and go to state 52 569 | '/' shift, and go to state 53 570 | 571 | '+' [reduce using rule 16 (expr)] 572 | '-' [reduce using rule 16 (expr)] 573 | '*' [reduce using rule 16 (expr)] 574 | '/' [reduce using rule 16 (expr)] 575 | $default reduce using rule 16 (expr) 576 | 577 | 578 | state 22 579 | 580 | 19 expr: expr_double . 581 | 35 expr_double: expr_double . '+' expr_double 582 | 36 | expr_double . '-' expr_double 583 | 37 | expr_double . '*' expr_double 584 | 38 | expr_double . '/' expr_double 585 | 586 | '+' shift, and go to state 54 587 | '-' shift, and go to state 55 588 | '*' shift, and go to state 56 589 | '/' shift, and go to state 57 590 | 591 | '+' [reduce using rule 19 (expr)] 592 | '-' [reduce using rule 19 (expr)] 593 | '*' [reduce using rule 19 (expr)] 594 | '/' [reduce using rule 19 (expr)] 595 | $default reduce using rule 19 (expr) 596 | 597 | 598 | state 23 599 | 600 | 20 expr: expr_string . 601 | 40 expr_string: expr_string . '+' expr_string 602 | 41 | expr_string . '+' expr_int 603 | 42 | expr_string . '+' expr_double 604 | 43 | expr_string . '+' expr_bool 605 | 606 | '+' shift, and go to state 58 607 | 608 | '+' [reduce using rule 20 (expr)] 609 | $default reduce using rule 20 (expr) 610 | 611 | 612 | state 24 613 | 614 | 18 expr: expr_bool . 615 | 616 | $default reduce using rule 18 (expr) 617 | 618 | 619 | state 25 620 | 621 | 46 expr_bool: expr_cmp_eq . 622 | 623 | $default reduce using rule 46 (expr_bool) 624 | 625 | 626 | state 26 627 | 628 | 47 expr_bool: expr_cmp_noteq . 629 | 630 | $default reduce using rule 47 (expr_bool) 631 | 632 | 633 | state 27 634 | 635 | 48 expr_bool: expr_cmp_greater . 636 | 637 | $default reduce using rule 48 (expr_bool) 638 | 639 | 640 | state 28 641 | 642 | 49 expr_bool: expr_cmp_smaller . 643 | 644 | $default reduce using rule 49 (expr_bool) 645 | 646 | 647 | state 29 648 | 649 | 50 expr_bool: expr_cmp_greaterequal . 650 | 651 | $default reduce using rule 50 (expr_bool) 652 | 653 | 654 | state 30 655 | 656 | 51 expr_bool: expr_cmp_smallerequal . 657 | 658 | $default reduce using rule 51 (expr_bool) 659 | 660 | 661 | state 31 662 | 663 | 34 expr_int: primary_int . 664 | 52 expr_cmp_eq: primary_int . EQUAL primary_int 665 | 54 expr_cmp_noteq: primary_int . NOTEQUAL primary_int 666 | 56 expr_cmp_greater: primary_int . '>' primary_int 667 | 58 expr_cmp_smaller: primary_int . '<' primary_int 668 | 60 expr_cmp_greaterequal: primary_int . GREATEREQUAL primary_int 669 | 62 expr_cmp_smallerequal: primary_int . SMALLEREQUAL primary_int 670 | 671 | EQUAL shift, and go to state 59 672 | NOTEQUAL shift, and go to state 60 673 | '<' shift, and go to state 61 674 | '>' shift, and go to state 62 675 | SMALLEREQUAL shift, and go to state 63 676 | GREATEREQUAL shift, and go to state 64 677 | 678 | $default reduce using rule 34 (expr_int) 679 | 680 | 681 | state 32 682 | 683 | 39 expr_double: primary_double . 684 | 685 | $default reduce using rule 39 (expr_double) 686 | 687 | 688 | state 33 689 | 690 | 44 expr_string: primary_string . 691 | 692 | $default reduce using rule 44 (expr_string) 693 | 694 | 695 | state 34 696 | 697 | 45 expr_bool: primary_bool . 698 | 53 expr_cmp_eq: primary_bool . EQUAL primary_bool 699 | 55 expr_cmp_noteq: primary_bool . NOTEQUAL primary_bool 700 | 57 expr_cmp_greater: primary_bool . '>' primary_bool 701 | 59 expr_cmp_smaller: primary_bool . '<' primary_bool 702 | 61 expr_cmp_greaterequal: primary_bool . GREATEREQUAL primary_bool 703 | 63 expr_cmp_smallerequal: primary_bool . SMALLEREQUAL primary_bool 704 | 705 | EQUAL shift, and go to state 65 706 | NOTEQUAL shift, and go to state 66 707 | '<' shift, and go to state 67 708 | '>' shift, and go to state 68 709 | SMALLEREQUAL shift, and go to state 69 710 | GREATEREQUAL shift, and go to state 70 711 | 712 | $default reduce using rule 45 (expr_bool) 713 | 714 | 715 | state 35 716 | 717 | 26 call_func: NAME '(' . set_var ')' 718 | 27 | NAME '(' . ')' 719 | 720 | NAME shift, and go to state 71 721 | ')' shift, and go to state 72 722 | 723 | set_var go to state 73 724 | 725 | 726 | state 36 727 | 728 | 13 set_var: NAME '=' . expr 729 | 730 | DOUBLE_LITERAL shift, and go to state 1 731 | INT_LITERAL shift, and go to state 2 732 | BOOL_LITERAL shift, and go to state 3 733 | STRING_LITERAL shift, and go to state 4 734 | NAME shift, and go to state 74 735 | PRINT shift, and go to state 6 736 | 737 | expr go to state 75 738 | call_func go to state 19 739 | expr_print go to state 20 740 | expr_int go to state 21 741 | expr_double go to state 22 742 | expr_string go to state 23 743 | expr_bool go to state 24 744 | expr_cmp_eq go to state 25 745 | expr_cmp_noteq go to state 26 746 | expr_cmp_greater go to state 27 747 | expr_cmp_smaller go to state 28 748 | expr_cmp_greaterequal go to state 29 749 | expr_cmp_smallerequal go to state 30 750 | primary_int go to state 31 751 | primary_double go to state 32 752 | primary_string go to state 33 753 | primary_bool go to state 34 754 | 755 | 756 | state 37 757 | 758 | 28 expr_print: PRINT '(' . stmt ')' 759 | 29 | PRINT '(' . expr ')' 760 | 761 | DOUBLE_LITERAL shift, and go to state 1 762 | INT_LITERAL shift, and go to state 2 763 | BOOL_LITERAL shift, and go to state 3 764 | STRING_LITERAL shift, and go to state 4 765 | NAME shift, and go to state 5 766 | PRINT shift, and go to state 6 767 | VAR shift, and go to state 7 768 | FUNCTION shift, and go to state 8 769 | IF shift, and go to state 9 770 | WHILE shift, and go to state 10 771 | 772 | stmt go to state 76 773 | def_func go to state 13 774 | def_var go to state 14 775 | set_var go to state 15 776 | if_stmt go to state 16 777 | while_stmt go to state 17 778 | expr go to state 77 779 | call_func go to state 19 780 | expr_print go to state 20 781 | expr_int go to state 21 782 | expr_double go to state 22 783 | expr_string go to state 23 784 | expr_bool go to state 24 785 | expr_cmp_eq go to state 25 786 | expr_cmp_noteq go to state 26 787 | expr_cmp_greater go to state 27 788 | expr_cmp_smaller go to state 28 789 | expr_cmp_greaterequal go to state 29 790 | expr_cmp_smallerequal go to state 30 791 | primary_int go to state 31 792 | primary_double go to state 32 793 | primary_string go to state 33 794 | primary_bool go to state 34 795 | 796 | 797 | state 38 798 | 799 | 12 def_var: VAR NAME . TYPE_LITERAL 800 | 801 | TYPE_LITERAL shift, and go to state 78 802 | 803 | 804 | state 39 805 | 806 | 10 def_func: FUNCTION NAME . '(' def_var ')' TYPE_LITERAL '{' stmt '}' 807 | 11 | FUNCTION NAME . '(' ')' TYPE_LITERAL '{' stmt '}' 808 | 809 | '(' shift, and go to state 79 810 | 811 | 812 | state 40 813 | 814 | 65 primary_int: NAME . 815 | 71 primary_bool: NAME . 816 | 817 | EQUAL reduce using rule 65 (primary_int) 818 | EQUAL [reduce using rule 71 (primary_bool)] 819 | NOTEQUAL reduce using rule 65 (primary_int) 820 | NOTEQUAL [reduce using rule 71 (primary_bool)] 821 | '<' reduce using rule 65 (primary_int) 822 | '<' [reduce using rule 71 (primary_bool)] 823 | '>' reduce using rule 65 (primary_int) 824 | '>' [reduce using rule 71 (primary_bool)] 825 | SMALLEREQUAL reduce using rule 65 (primary_int) 826 | SMALLEREQUAL [reduce using rule 71 (primary_bool)] 827 | GREATEREQUAL reduce using rule 65 (primary_int) 828 | GREATEREQUAL [reduce using rule 71 (primary_bool)] 829 | '{' reduce using rule 71 (primary_bool) 830 | $default reduce using rule 65 (primary_int) 831 | 832 | 833 | state 41 834 | 835 | 14 if_stmt: IF expr_bool . '{' stmt '}' ELSE '{' stmt '}' 836 | 837 | '{' shift, and go to state 80 838 | 839 | 840 | state 42 841 | 842 | 52 expr_cmp_eq: primary_int . EQUAL primary_int 843 | 54 expr_cmp_noteq: primary_int . NOTEQUAL primary_int 844 | 56 expr_cmp_greater: primary_int . '>' primary_int 845 | 58 expr_cmp_smaller: primary_int . '<' primary_int 846 | 60 expr_cmp_greaterequal: primary_int . GREATEREQUAL primary_int 847 | 62 expr_cmp_smallerequal: primary_int . SMALLEREQUAL primary_int 848 | 849 | EQUAL shift, and go to state 59 850 | NOTEQUAL shift, and go to state 60 851 | '<' shift, and go to state 61 852 | '>' shift, and go to state 62 853 | SMALLEREQUAL shift, and go to state 63 854 | GREATEREQUAL shift, and go to state 64 855 | 856 | 857 | state 43 858 | 859 | 15 while_stmt: WHILE expr_bool . '{' stmt '}' 860 | 861 | '{' shift, and go to state 81 862 | 863 | 864 | state 44 865 | 866 | 0 $accept: prog $end . 867 | 868 | $default accept 869 | 870 | 871 | state 45 872 | 873 | 9 stmt: stmt . stmt 874 | 9 | stmt stmt . 875 | 876 | DOUBLE_LITERAL shift, and go to state 1 877 | INT_LITERAL shift, and go to state 2 878 | BOOL_LITERAL shift, and go to state 3 879 | STRING_LITERAL shift, and go to state 4 880 | NAME shift, and go to state 5 881 | PRINT shift, and go to state 6 882 | VAR shift, and go to state 7 883 | FUNCTION shift, and go to state 8 884 | IF shift, and go to state 9 885 | WHILE shift, and go to state 10 886 | 887 | DOUBLE_LITERAL [reduce using rule 9 (stmt)] 888 | INT_LITERAL [reduce using rule 9 (stmt)] 889 | BOOL_LITERAL [reduce using rule 9 (stmt)] 890 | STRING_LITERAL [reduce using rule 9 (stmt)] 891 | NAME [reduce using rule 9 (stmt)] 892 | PRINT [reduce using rule 9 (stmt)] 893 | VAR [reduce using rule 9 (stmt)] 894 | FUNCTION [reduce using rule 9 (stmt)] 895 | IF [reduce using rule 9 (stmt)] 896 | WHILE [reduce using rule 9 (stmt)] 897 | $default reduce using rule 9 (stmt) 898 | 899 | stmt go to state 45 900 | def_func go to state 13 901 | def_var go to state 14 902 | set_var go to state 15 903 | if_stmt go to state 16 904 | while_stmt go to state 17 905 | expr go to state 18 906 | call_func go to state 19 907 | expr_print go to state 20 908 | expr_int go to state 21 909 | expr_double go to state 22 910 | expr_string go to state 23 911 | expr_bool go to state 24 912 | expr_cmp_eq go to state 25 913 | expr_cmp_noteq go to state 26 914 | expr_cmp_greater go to state 27 915 | expr_cmp_smaller go to state 28 916 | expr_cmp_greaterequal go to state 29 917 | expr_cmp_smallerequal go to state 30 918 | primary_int go to state 31 919 | primary_double go to state 32 920 | primary_string go to state 33 921 | primary_bool go to state 34 922 | 923 | 924 | state 46 925 | 926 | 22 expr: expr '+' . expr 927 | 928 | DOUBLE_LITERAL shift, and go to state 1 929 | INT_LITERAL shift, and go to state 2 930 | BOOL_LITERAL shift, and go to state 3 931 | STRING_LITERAL shift, and go to state 4 932 | NAME shift, and go to state 74 933 | PRINT shift, and go to state 6 934 | 935 | expr go to state 82 936 | call_func go to state 19 937 | expr_print go to state 20 938 | expr_int go to state 21 939 | expr_double go to state 22 940 | expr_string go to state 23 941 | expr_bool go to state 24 942 | expr_cmp_eq go to state 25 943 | expr_cmp_noteq go to state 26 944 | expr_cmp_greater go to state 27 945 | expr_cmp_smaller go to state 28 946 | expr_cmp_greaterequal go to state 29 947 | expr_cmp_smallerequal go to state 30 948 | primary_int go to state 31 949 | primary_double go to state 32 950 | primary_string go to state 33 951 | primary_bool go to state 34 952 | 953 | 954 | state 47 955 | 956 | 23 expr: expr '-' . expr 957 | 958 | DOUBLE_LITERAL shift, and go to state 1 959 | INT_LITERAL shift, and go to state 2 960 | BOOL_LITERAL shift, and go to state 3 961 | STRING_LITERAL shift, and go to state 4 962 | NAME shift, and go to state 74 963 | PRINT shift, and go to state 6 964 | 965 | expr go to state 83 966 | call_func go to state 19 967 | expr_print go to state 20 968 | expr_int go to state 21 969 | expr_double go to state 22 970 | expr_string go to state 23 971 | expr_bool go to state 24 972 | expr_cmp_eq go to state 25 973 | expr_cmp_noteq go to state 26 974 | expr_cmp_greater go to state 27 975 | expr_cmp_smaller go to state 28 976 | expr_cmp_greaterequal go to state 29 977 | expr_cmp_smallerequal go to state 30 978 | primary_int go to state 31 979 | primary_double go to state 32 980 | primary_string go to state 33 981 | primary_bool go to state 34 982 | 983 | 984 | state 48 985 | 986 | 24 expr: expr '*' . expr 987 | 988 | DOUBLE_LITERAL shift, and go to state 1 989 | INT_LITERAL shift, and go to state 2 990 | BOOL_LITERAL shift, and go to state 3 991 | STRING_LITERAL shift, and go to state 4 992 | NAME shift, and go to state 74 993 | PRINT shift, and go to state 6 994 | 995 | expr go to state 84 996 | call_func go to state 19 997 | expr_print go to state 20 998 | expr_int go to state 21 999 | expr_double go to state 22 1000 | expr_string go to state 23 1001 | expr_bool go to state 24 1002 | expr_cmp_eq go to state 25 1003 | expr_cmp_noteq go to state 26 1004 | expr_cmp_greater go to state 27 1005 | expr_cmp_smaller go to state 28 1006 | expr_cmp_greaterequal go to state 29 1007 | expr_cmp_smallerequal go to state 30 1008 | primary_int go to state 31 1009 | primary_double go to state 32 1010 | primary_string go to state 33 1011 | primary_bool go to state 34 1012 | 1013 | 1014 | state 49 1015 | 1016 | 25 expr: expr '/' . expr 1017 | 1018 | DOUBLE_LITERAL shift, and go to state 1 1019 | INT_LITERAL shift, and go to state 2 1020 | BOOL_LITERAL shift, and go to state 3 1021 | STRING_LITERAL shift, and go to state 4 1022 | NAME shift, and go to state 74 1023 | PRINT shift, and go to state 6 1024 | 1025 | expr go to state 85 1026 | call_func go to state 19 1027 | expr_print go to state 20 1028 | expr_int go to state 21 1029 | expr_double go to state 22 1030 | expr_string go to state 23 1031 | expr_bool go to state 24 1032 | expr_cmp_eq go to state 25 1033 | expr_cmp_noteq go to state 26 1034 | expr_cmp_greater go to state 27 1035 | expr_cmp_smaller go to state 28 1036 | expr_cmp_greaterequal go to state 29 1037 | expr_cmp_smallerequal go to state 30 1038 | primary_int go to state 31 1039 | primary_double go to state 32 1040 | primary_string go to state 33 1041 | primary_bool go to state 34 1042 | 1043 | 1044 | state 50 1045 | 1046 | 30 expr_int: expr_int '+' . expr_int 1047 | 1048 | INT_LITERAL shift, and go to state 2 1049 | NAME shift, and go to state 86 1050 | 1051 | expr_int go to state 87 1052 | primary_int go to state 88 1053 | 1054 | 1055 | state 51 1056 | 1057 | 31 expr_int: expr_int '-' . expr_int 1058 | 1059 | INT_LITERAL shift, and go to state 2 1060 | NAME shift, and go to state 86 1061 | 1062 | expr_int go to state 89 1063 | primary_int go to state 88 1064 | 1065 | 1066 | state 52 1067 | 1068 | 32 expr_int: expr_int '*' . expr_int 1069 | 1070 | INT_LITERAL shift, and go to state 2 1071 | NAME shift, and go to state 86 1072 | 1073 | expr_int go to state 90 1074 | primary_int go to state 88 1075 | 1076 | 1077 | state 53 1078 | 1079 | 33 expr_int: expr_int '/' . expr_int 1080 | 1081 | INT_LITERAL shift, and go to state 2 1082 | NAME shift, and go to state 86 1083 | 1084 | expr_int go to state 91 1085 | primary_int go to state 88 1086 | 1087 | 1088 | state 54 1089 | 1090 | 35 expr_double: expr_double '+' . expr_double 1091 | 1092 | DOUBLE_LITERAL shift, and go to state 1 1093 | NAME shift, and go to state 92 1094 | 1095 | expr_double go to state 93 1096 | primary_double go to state 32 1097 | 1098 | 1099 | state 55 1100 | 1101 | 36 expr_double: expr_double '-' . expr_double 1102 | 1103 | DOUBLE_LITERAL shift, and go to state 1 1104 | NAME shift, and go to state 92 1105 | 1106 | expr_double go to state 94 1107 | primary_double go to state 32 1108 | 1109 | 1110 | state 56 1111 | 1112 | 37 expr_double: expr_double '*' . expr_double 1113 | 1114 | DOUBLE_LITERAL shift, and go to state 1 1115 | NAME shift, and go to state 92 1116 | 1117 | expr_double go to state 95 1118 | primary_double go to state 32 1119 | 1120 | 1121 | state 57 1122 | 1123 | 38 expr_double: expr_double '/' . expr_double 1124 | 1125 | DOUBLE_LITERAL shift, and go to state 1 1126 | NAME shift, and go to state 92 1127 | 1128 | expr_double go to state 96 1129 | primary_double go to state 32 1130 | 1131 | 1132 | state 58 1133 | 1134 | 40 expr_string: expr_string '+' . expr_string 1135 | 41 | expr_string '+' . expr_int 1136 | 42 | expr_string '+' . expr_double 1137 | 43 | expr_string '+' . expr_bool 1138 | 1139 | DOUBLE_LITERAL shift, and go to state 1 1140 | INT_LITERAL shift, and go to state 2 1141 | BOOL_LITERAL shift, and go to state 3 1142 | STRING_LITERAL shift, and go to state 4 1143 | NAME shift, and go to state 97 1144 | 1145 | expr_int go to state 98 1146 | expr_double go to state 99 1147 | expr_string go to state 100 1148 | expr_bool go to state 101 1149 | expr_cmp_eq go to state 25 1150 | expr_cmp_noteq go to state 26 1151 | expr_cmp_greater go to state 27 1152 | expr_cmp_smaller go to state 28 1153 | expr_cmp_greaterequal go to state 29 1154 | expr_cmp_smallerequal go to state 30 1155 | primary_int go to state 31 1156 | primary_double go to state 32 1157 | primary_string go to state 33 1158 | primary_bool go to state 34 1159 | 1160 | 1161 | state 59 1162 | 1163 | 52 expr_cmp_eq: primary_int EQUAL . primary_int 1164 | 1165 | INT_LITERAL shift, and go to state 2 1166 | NAME shift, and go to state 86 1167 | 1168 | primary_int go to state 102 1169 | 1170 | 1171 | state 60 1172 | 1173 | 54 expr_cmp_noteq: primary_int NOTEQUAL . primary_int 1174 | 1175 | INT_LITERAL shift, and go to state 2 1176 | NAME shift, and go to state 86 1177 | 1178 | primary_int go to state 103 1179 | 1180 | 1181 | state 61 1182 | 1183 | 58 expr_cmp_smaller: primary_int '<' . primary_int 1184 | 1185 | INT_LITERAL shift, and go to state 2 1186 | NAME shift, and go to state 86 1187 | 1188 | primary_int go to state 104 1189 | 1190 | 1191 | state 62 1192 | 1193 | 56 expr_cmp_greater: primary_int '>' . primary_int 1194 | 1195 | INT_LITERAL shift, and go to state 2 1196 | NAME shift, and go to state 86 1197 | 1198 | primary_int go to state 105 1199 | 1200 | 1201 | state 63 1202 | 1203 | 62 expr_cmp_smallerequal: primary_int SMALLEREQUAL . primary_int 1204 | 1205 | INT_LITERAL shift, and go to state 2 1206 | NAME shift, and go to state 86 1207 | 1208 | primary_int go to state 106 1209 | 1210 | 1211 | state 64 1212 | 1213 | 60 expr_cmp_greaterequal: primary_int GREATEREQUAL . primary_int 1214 | 1215 | INT_LITERAL shift, and go to state 2 1216 | NAME shift, and go to state 86 1217 | 1218 | primary_int go to state 107 1219 | 1220 | 1221 | state 65 1222 | 1223 | 53 expr_cmp_eq: primary_bool EQUAL . primary_bool 1224 | 1225 | BOOL_LITERAL shift, and go to state 3 1226 | NAME shift, and go to state 108 1227 | 1228 | primary_bool go to state 109 1229 | 1230 | 1231 | state 66 1232 | 1233 | 55 expr_cmp_noteq: primary_bool NOTEQUAL . primary_bool 1234 | 1235 | BOOL_LITERAL shift, and go to state 3 1236 | NAME shift, and go to state 108 1237 | 1238 | primary_bool go to state 110 1239 | 1240 | 1241 | state 67 1242 | 1243 | 59 expr_cmp_smaller: primary_bool '<' . primary_bool 1244 | 1245 | BOOL_LITERAL shift, and go to state 3 1246 | NAME shift, and go to state 108 1247 | 1248 | primary_bool go to state 111 1249 | 1250 | 1251 | state 68 1252 | 1253 | 57 expr_cmp_greater: primary_bool '>' . primary_bool 1254 | 1255 | BOOL_LITERAL shift, and go to state 3 1256 | NAME shift, and go to state 108 1257 | 1258 | primary_bool go to state 112 1259 | 1260 | 1261 | state 69 1262 | 1263 | 63 expr_cmp_smallerequal: primary_bool SMALLEREQUAL . primary_bool 1264 | 1265 | BOOL_LITERAL shift, and go to state 3 1266 | NAME shift, and go to state 108 1267 | 1268 | primary_bool go to state 113 1269 | 1270 | 1271 | state 70 1272 | 1273 | 61 expr_cmp_greaterequal: primary_bool GREATEREQUAL . primary_bool 1274 | 1275 | BOOL_LITERAL shift, and go to state 3 1276 | NAME shift, and go to state 108 1277 | 1278 | primary_bool go to state 114 1279 | 1280 | 1281 | state 71 1282 | 1283 | 13 set_var: NAME . '=' expr 1284 | 1285 | '=' shift, and go to state 36 1286 | 1287 | 1288 | state 72 1289 | 1290 | 27 call_func: NAME '(' ')' . 1291 | 1292 | $default reduce using rule 27 (call_func) 1293 | 1294 | 1295 | state 73 1296 | 1297 | 26 call_func: NAME '(' set_var . ')' 1298 | 1299 | ')' shift, and go to state 115 1300 | 1301 | 1302 | state 74 1303 | 1304 | 26 call_func: NAME . '(' set_var ')' 1305 | 27 | NAME . '(' ')' 1306 | 65 primary_int: NAME . 1307 | 67 primary_double: NAME . 1308 | 69 primary_string: NAME . 1309 | 71 primary_bool: NAME . 1310 | 1311 | '(' shift, and go to state 35 1312 | 1313 | $end reduce using rule 65 (primary_int) 1314 | $end [reduce using rule 67 (primary_double)] 1315 | $end [reduce using rule 69 (primary_string)] 1316 | $end [reduce using rule 71 (primary_bool)] 1317 | DOUBLE_LITERAL reduce using rule 65 (primary_int) 1318 | DOUBLE_LITERAL [reduce using rule 67 (primary_double)] 1319 | DOUBLE_LITERAL [reduce using rule 69 (primary_string)] 1320 | DOUBLE_LITERAL [reduce using rule 71 (primary_bool)] 1321 | INT_LITERAL reduce using rule 65 (primary_int) 1322 | INT_LITERAL [reduce using rule 67 (primary_double)] 1323 | INT_LITERAL [reduce using rule 69 (primary_string)] 1324 | INT_LITERAL [reduce using rule 71 (primary_bool)] 1325 | BOOL_LITERAL reduce using rule 65 (primary_int) 1326 | BOOL_LITERAL [reduce using rule 67 (primary_double)] 1327 | BOOL_LITERAL [reduce using rule 69 (primary_string)] 1328 | BOOL_LITERAL [reduce using rule 71 (primary_bool)] 1329 | STRING_LITERAL reduce using rule 65 (primary_int) 1330 | STRING_LITERAL [reduce using rule 67 (primary_double)] 1331 | STRING_LITERAL [reduce using rule 69 (primary_string)] 1332 | STRING_LITERAL [reduce using rule 71 (primary_bool)] 1333 | NAME reduce using rule 65 (primary_int) 1334 | NAME [reduce using rule 67 (primary_double)] 1335 | NAME [reduce using rule 69 (primary_string)] 1336 | NAME [reduce using rule 71 (primary_bool)] 1337 | '+' reduce using rule 65 (primary_int) 1338 | '+' [reduce using rule 67 (primary_double)] 1339 | '+' [reduce using rule 69 (primary_string)] 1340 | '+' [reduce using rule 71 (primary_bool)] 1341 | '-' reduce using rule 65 (primary_int) 1342 | '-' [reduce using rule 67 (primary_double)] 1343 | '-' [reduce using rule 69 (primary_string)] 1344 | '-' [reduce using rule 71 (primary_bool)] 1345 | '*' reduce using rule 65 (primary_int) 1346 | '*' [reduce using rule 67 (primary_double)] 1347 | '*' [reduce using rule 69 (primary_string)] 1348 | '*' [reduce using rule 71 (primary_bool)] 1349 | '/' reduce using rule 65 (primary_int) 1350 | '/' [reduce using rule 67 (primary_double)] 1351 | '/' [reduce using rule 69 (primary_string)] 1352 | '/' [reduce using rule 71 (primary_bool)] 1353 | ')' reduce using rule 65 (primary_int) 1354 | ')' [reduce using rule 67 (primary_double)] 1355 | ')' [reduce using rule 69 (primary_string)] 1356 | ')' [reduce using rule 71 (primary_bool)] 1357 | EQUAL reduce using rule 65 (primary_int) 1358 | EQUAL [reduce using rule 71 (primary_bool)] 1359 | PRINT reduce using rule 65 (primary_int) 1360 | PRINT [reduce using rule 67 (primary_double)] 1361 | PRINT [reduce using rule 69 (primary_string)] 1362 | PRINT [reduce using rule 71 (primary_bool)] 1363 | VAR reduce using rule 65 (primary_int) 1364 | VAR [reduce using rule 67 (primary_double)] 1365 | VAR [reduce using rule 69 (primary_string)] 1366 | VAR [reduce using rule 71 (primary_bool)] 1367 | FUNCTION reduce using rule 65 (primary_int) 1368 | FUNCTION [reduce using rule 67 (primary_double)] 1369 | FUNCTION [reduce using rule 69 (primary_string)] 1370 | FUNCTION [reduce using rule 71 (primary_bool)] 1371 | NOTEQUAL reduce using rule 65 (primary_int) 1372 | NOTEQUAL [reduce using rule 71 (primary_bool)] 1373 | '<' reduce using rule 65 (primary_int) 1374 | '<' [reduce using rule 71 (primary_bool)] 1375 | '>' reduce using rule 65 (primary_int) 1376 | '>' [reduce using rule 71 (primary_bool)] 1377 | SMALLEREQUAL reduce using rule 65 (primary_int) 1378 | SMALLEREQUAL [reduce using rule 71 (primary_bool)] 1379 | GREATEREQUAL reduce using rule 65 (primary_int) 1380 | GREATEREQUAL [reduce using rule 71 (primary_bool)] 1381 | IF reduce using rule 65 (primary_int) 1382 | IF [reduce using rule 67 (primary_double)] 1383 | IF [reduce using rule 69 (primary_string)] 1384 | IF [reduce using rule 71 (primary_bool)] 1385 | WHILE reduce using rule 65 (primary_int) 1386 | WHILE [reduce using rule 67 (primary_double)] 1387 | WHILE [reduce using rule 69 (primary_string)] 1388 | WHILE [reduce using rule 71 (primary_bool)] 1389 | '}' reduce using rule 65 (primary_int) 1390 | '}' [reduce using rule 67 (primary_double)] 1391 | '}' [reduce using rule 69 (primary_string)] 1392 | '}' [reduce using rule 71 (primary_bool)] 1393 | $default reduce using rule 65 (primary_int) 1394 | 1395 | 1396 | state 75 1397 | 1398 | 13 set_var: NAME '=' expr . 1399 | 22 expr: expr . '+' expr 1400 | 23 | expr . '-' expr 1401 | 24 | expr . '*' expr 1402 | 25 | expr . '/' expr 1403 | 1404 | '+' shift, and go to state 46 1405 | '-' shift, and go to state 47 1406 | '*' shift, and go to state 48 1407 | '/' shift, and go to state 49 1408 | 1409 | $default reduce using rule 13 (set_var) 1410 | 1411 | 1412 | state 76 1413 | 1414 | 9 stmt: stmt . stmt 1415 | 28 expr_print: PRINT '(' stmt . ')' 1416 | 1417 | DOUBLE_LITERAL shift, and go to state 1 1418 | INT_LITERAL shift, and go to state 2 1419 | BOOL_LITERAL shift, and go to state 3 1420 | STRING_LITERAL shift, and go to state 4 1421 | NAME shift, and go to state 5 1422 | ')' shift, and go to state 116 1423 | PRINT shift, and go to state 6 1424 | VAR shift, and go to state 7 1425 | FUNCTION shift, and go to state 8 1426 | IF shift, and go to state 9 1427 | WHILE shift, and go to state 10 1428 | 1429 | stmt go to state 45 1430 | def_func go to state 13 1431 | def_var go to state 14 1432 | set_var go to state 15 1433 | if_stmt go to state 16 1434 | while_stmt go to state 17 1435 | expr go to state 18 1436 | call_func go to state 19 1437 | expr_print go to state 20 1438 | expr_int go to state 21 1439 | expr_double go to state 22 1440 | expr_string go to state 23 1441 | expr_bool go to state 24 1442 | expr_cmp_eq go to state 25 1443 | expr_cmp_noteq go to state 26 1444 | expr_cmp_greater go to state 27 1445 | expr_cmp_smaller go to state 28 1446 | expr_cmp_greaterequal go to state 29 1447 | expr_cmp_smallerequal go to state 30 1448 | primary_int go to state 31 1449 | primary_double go to state 32 1450 | primary_string go to state 33 1451 | primary_bool go to state 34 1452 | 1453 | 1454 | state 77 1455 | 1456 | 3 stmt: expr . 1457 | 22 expr: expr . '+' expr 1458 | 23 | expr . '-' expr 1459 | 24 | expr . '*' expr 1460 | 25 | expr . '/' expr 1461 | 29 expr_print: PRINT '(' expr . ')' 1462 | 1463 | '+' shift, and go to state 46 1464 | '-' shift, and go to state 47 1465 | '*' shift, and go to state 48 1466 | '/' shift, and go to state 49 1467 | ')' shift, and go to state 117 1468 | 1469 | ')' [reduce using rule 3 (stmt)] 1470 | $default reduce using rule 3 (stmt) 1471 | 1472 | 1473 | state 78 1474 | 1475 | 12 def_var: VAR NAME TYPE_LITERAL . 1476 | 1477 | $default reduce using rule 12 (def_var) 1478 | 1479 | 1480 | state 79 1481 | 1482 | 10 def_func: FUNCTION NAME '(' . def_var ')' TYPE_LITERAL '{' stmt '}' 1483 | 11 | FUNCTION NAME '(' . ')' TYPE_LITERAL '{' stmt '}' 1484 | 1485 | ')' shift, and go to state 118 1486 | VAR shift, and go to state 7 1487 | 1488 | def_var go to state 119 1489 | 1490 | 1491 | state 80 1492 | 1493 | 14 if_stmt: IF expr_bool '{' . stmt '}' ELSE '{' stmt '}' 1494 | 1495 | DOUBLE_LITERAL shift, and go to state 1 1496 | INT_LITERAL shift, and go to state 2 1497 | BOOL_LITERAL shift, and go to state 3 1498 | STRING_LITERAL shift, and go to state 4 1499 | NAME shift, and go to state 5 1500 | PRINT shift, and go to state 6 1501 | VAR shift, and go to state 7 1502 | FUNCTION shift, and go to state 8 1503 | IF shift, and go to state 9 1504 | WHILE shift, and go to state 10 1505 | 1506 | stmt go to state 120 1507 | def_func go to state 13 1508 | def_var go to state 14 1509 | set_var go to state 15 1510 | if_stmt go to state 16 1511 | while_stmt go to state 17 1512 | expr go to state 18 1513 | call_func go to state 19 1514 | expr_print go to state 20 1515 | expr_int go to state 21 1516 | expr_double go to state 22 1517 | expr_string go to state 23 1518 | expr_bool go to state 24 1519 | expr_cmp_eq go to state 25 1520 | expr_cmp_noteq go to state 26 1521 | expr_cmp_greater go to state 27 1522 | expr_cmp_smaller go to state 28 1523 | expr_cmp_greaterequal go to state 29 1524 | expr_cmp_smallerequal go to state 30 1525 | primary_int go to state 31 1526 | primary_double go to state 32 1527 | primary_string go to state 33 1528 | primary_bool go to state 34 1529 | 1530 | 1531 | state 81 1532 | 1533 | 15 while_stmt: WHILE expr_bool '{' . stmt '}' 1534 | 1535 | DOUBLE_LITERAL shift, and go to state 1 1536 | INT_LITERAL shift, and go to state 2 1537 | BOOL_LITERAL shift, and go to state 3 1538 | STRING_LITERAL shift, and go to state 4 1539 | NAME shift, and go to state 5 1540 | PRINT shift, and go to state 6 1541 | VAR shift, and go to state 7 1542 | FUNCTION shift, and go to state 8 1543 | IF shift, and go to state 9 1544 | WHILE shift, and go to state 10 1545 | 1546 | stmt go to state 121 1547 | def_func go to state 13 1548 | def_var go to state 14 1549 | set_var go to state 15 1550 | if_stmt go to state 16 1551 | while_stmt go to state 17 1552 | expr go to state 18 1553 | call_func go to state 19 1554 | expr_print go to state 20 1555 | expr_int go to state 21 1556 | expr_double go to state 22 1557 | expr_string go to state 23 1558 | expr_bool go to state 24 1559 | expr_cmp_eq go to state 25 1560 | expr_cmp_noteq go to state 26 1561 | expr_cmp_greater go to state 27 1562 | expr_cmp_smaller go to state 28 1563 | expr_cmp_greaterequal go to state 29 1564 | expr_cmp_smallerequal go to state 30 1565 | primary_int go to state 31 1566 | primary_double go to state 32 1567 | primary_string go to state 33 1568 | primary_bool go to state 34 1569 | 1570 | 1571 | state 82 1572 | 1573 | 22 expr: expr . '+' expr 1574 | 22 | expr '+' expr . 1575 | 23 | expr . '-' expr 1576 | 24 | expr . '*' expr 1577 | 25 | expr . '/' expr 1578 | 1579 | '*' shift, and go to state 48 1580 | '/' shift, and go to state 49 1581 | 1582 | $default reduce using rule 22 (expr) 1583 | 1584 | 1585 | state 83 1586 | 1587 | 22 expr: expr . '+' expr 1588 | 23 | expr . '-' expr 1589 | 23 | expr '-' expr . 1590 | 24 | expr . '*' expr 1591 | 25 | expr . '/' expr 1592 | 1593 | '*' shift, and go to state 48 1594 | '/' shift, and go to state 49 1595 | 1596 | $default reduce using rule 23 (expr) 1597 | 1598 | 1599 | state 84 1600 | 1601 | 22 expr: expr . '+' expr 1602 | 23 | expr . '-' expr 1603 | 24 | expr . '*' expr 1604 | 24 | expr '*' expr . 1605 | 25 | expr . '/' expr 1606 | 1607 | $default reduce using rule 24 (expr) 1608 | 1609 | 1610 | state 85 1611 | 1612 | 22 expr: expr . '+' expr 1613 | 23 | expr . '-' expr 1614 | 24 | expr . '*' expr 1615 | 25 | expr . '/' expr 1616 | 25 | expr '/' expr . 1617 | 1618 | $default reduce using rule 25 (expr) 1619 | 1620 | 1621 | state 86 1622 | 1623 | 65 primary_int: NAME . 1624 | 1625 | $default reduce using rule 65 (primary_int) 1626 | 1627 | 1628 | state 87 1629 | 1630 | 30 expr_int: expr_int . '+' expr_int 1631 | 30 | expr_int '+' expr_int . 1632 | 31 | expr_int . '-' expr_int 1633 | 32 | expr_int . '*' expr_int 1634 | 33 | expr_int . '/' expr_int 1635 | 1636 | '*' shift, and go to state 52 1637 | '/' shift, and go to state 53 1638 | 1639 | $default reduce using rule 30 (expr_int) 1640 | 1641 | 1642 | state 88 1643 | 1644 | 34 expr_int: primary_int . 1645 | 1646 | $default reduce using rule 34 (expr_int) 1647 | 1648 | 1649 | state 89 1650 | 1651 | 30 expr_int: expr_int . '+' expr_int 1652 | 31 | expr_int . '-' expr_int 1653 | 31 | expr_int '-' expr_int . 1654 | 32 | expr_int . '*' expr_int 1655 | 33 | expr_int . '/' expr_int 1656 | 1657 | '*' shift, and go to state 52 1658 | '/' shift, and go to state 53 1659 | 1660 | $default reduce using rule 31 (expr_int) 1661 | 1662 | 1663 | state 90 1664 | 1665 | 30 expr_int: expr_int . '+' expr_int 1666 | 31 | expr_int . '-' expr_int 1667 | 32 | expr_int . '*' expr_int 1668 | 32 | expr_int '*' expr_int . 1669 | 33 | expr_int . '/' expr_int 1670 | 1671 | $default reduce using rule 32 (expr_int) 1672 | 1673 | 1674 | state 91 1675 | 1676 | 30 expr_int: expr_int . '+' expr_int 1677 | 31 | expr_int . '-' expr_int 1678 | 32 | expr_int . '*' expr_int 1679 | 33 | expr_int . '/' expr_int 1680 | 33 | expr_int '/' expr_int . 1681 | 1682 | $default reduce using rule 33 (expr_int) 1683 | 1684 | 1685 | state 92 1686 | 1687 | 67 primary_double: NAME . 1688 | 1689 | $default reduce using rule 67 (primary_double) 1690 | 1691 | 1692 | state 93 1693 | 1694 | 35 expr_double: expr_double . '+' expr_double 1695 | 35 | expr_double '+' expr_double . 1696 | 36 | expr_double . '-' expr_double 1697 | 37 | expr_double . '*' expr_double 1698 | 38 | expr_double . '/' expr_double 1699 | 1700 | '*' shift, and go to state 56 1701 | '/' shift, and go to state 57 1702 | 1703 | $default reduce using rule 35 (expr_double) 1704 | 1705 | 1706 | state 94 1707 | 1708 | 35 expr_double: expr_double . '+' expr_double 1709 | 36 | expr_double . '-' expr_double 1710 | 36 | expr_double '-' expr_double . 1711 | 37 | expr_double . '*' expr_double 1712 | 38 | expr_double . '/' expr_double 1713 | 1714 | '*' shift, and go to state 56 1715 | '/' shift, and go to state 57 1716 | 1717 | $default reduce using rule 36 (expr_double) 1718 | 1719 | 1720 | state 95 1721 | 1722 | 35 expr_double: expr_double . '+' expr_double 1723 | 36 | expr_double . '-' expr_double 1724 | 37 | expr_double . '*' expr_double 1725 | 37 | expr_double '*' expr_double . 1726 | 38 | expr_double . '/' expr_double 1727 | 1728 | $default reduce using rule 37 (expr_double) 1729 | 1730 | 1731 | state 96 1732 | 1733 | 35 expr_double: expr_double . '+' expr_double 1734 | 36 | expr_double . '-' expr_double 1735 | 37 | expr_double . '*' expr_double 1736 | 38 | expr_double . '/' expr_double 1737 | 38 | expr_double '/' expr_double . 1738 | 1739 | $default reduce using rule 38 (expr_double) 1740 | 1741 | 1742 | state 97 1743 | 1744 | 65 primary_int: NAME . 1745 | 67 primary_double: NAME . 1746 | 69 primary_string: NAME . 1747 | 71 primary_bool: NAME . 1748 | 1749 | $end reduce using rule 65 (primary_int) 1750 | $end [reduce using rule 67 (primary_double)] 1751 | $end [reduce using rule 69 (primary_string)] 1752 | $end [reduce using rule 71 (primary_bool)] 1753 | DOUBLE_LITERAL reduce using rule 65 (primary_int) 1754 | DOUBLE_LITERAL [reduce using rule 67 (primary_double)] 1755 | DOUBLE_LITERAL [reduce using rule 69 (primary_string)] 1756 | DOUBLE_LITERAL [reduce using rule 71 (primary_bool)] 1757 | INT_LITERAL reduce using rule 65 (primary_int) 1758 | INT_LITERAL [reduce using rule 67 (primary_double)] 1759 | INT_LITERAL [reduce using rule 69 (primary_string)] 1760 | INT_LITERAL [reduce using rule 71 (primary_bool)] 1761 | BOOL_LITERAL reduce using rule 65 (primary_int) 1762 | BOOL_LITERAL [reduce using rule 67 (primary_double)] 1763 | BOOL_LITERAL [reduce using rule 69 (primary_string)] 1764 | BOOL_LITERAL [reduce using rule 71 (primary_bool)] 1765 | STRING_LITERAL reduce using rule 65 (primary_int) 1766 | STRING_LITERAL [reduce using rule 67 (primary_double)] 1767 | STRING_LITERAL [reduce using rule 69 (primary_string)] 1768 | STRING_LITERAL [reduce using rule 71 (primary_bool)] 1769 | NAME reduce using rule 65 (primary_int) 1770 | NAME [reduce using rule 67 (primary_double)] 1771 | NAME [reduce using rule 69 (primary_string)] 1772 | NAME [reduce using rule 71 (primary_bool)] 1773 | '+' reduce using rule 65 (primary_int) 1774 | '+' [reduce using rule 67 (primary_double)] 1775 | '+' [reduce using rule 69 (primary_string)] 1776 | '+' [reduce using rule 71 (primary_bool)] 1777 | '-' reduce using rule 65 (primary_int) 1778 | '-' [reduce using rule 67 (primary_double)] 1779 | '-' [reduce using rule 69 (primary_string)] 1780 | '-' [reduce using rule 71 (primary_bool)] 1781 | '*' reduce using rule 65 (primary_int) 1782 | '*' [reduce using rule 67 (primary_double)] 1783 | '*' [reduce using rule 69 (primary_string)] 1784 | '*' [reduce using rule 71 (primary_bool)] 1785 | '/' reduce using rule 65 (primary_int) 1786 | '/' [reduce using rule 67 (primary_double)] 1787 | '/' [reduce using rule 69 (primary_string)] 1788 | '/' [reduce using rule 71 (primary_bool)] 1789 | ')' reduce using rule 65 (primary_int) 1790 | ')' [reduce using rule 67 (primary_double)] 1791 | ')' [reduce using rule 69 (primary_string)] 1792 | ')' [reduce using rule 71 (primary_bool)] 1793 | EQUAL reduce using rule 65 (primary_int) 1794 | EQUAL [reduce using rule 71 (primary_bool)] 1795 | PRINT reduce using rule 65 (primary_int) 1796 | PRINT [reduce using rule 67 (primary_double)] 1797 | PRINT [reduce using rule 69 (primary_string)] 1798 | PRINT [reduce using rule 71 (primary_bool)] 1799 | VAR reduce using rule 65 (primary_int) 1800 | VAR [reduce using rule 67 (primary_double)] 1801 | VAR [reduce using rule 69 (primary_string)] 1802 | VAR [reduce using rule 71 (primary_bool)] 1803 | FUNCTION reduce using rule 65 (primary_int) 1804 | FUNCTION [reduce using rule 67 (primary_double)] 1805 | FUNCTION [reduce using rule 69 (primary_string)] 1806 | FUNCTION [reduce using rule 71 (primary_bool)] 1807 | NOTEQUAL reduce using rule 65 (primary_int) 1808 | NOTEQUAL [reduce using rule 71 (primary_bool)] 1809 | '<' reduce using rule 65 (primary_int) 1810 | '<' [reduce using rule 71 (primary_bool)] 1811 | '>' reduce using rule 65 (primary_int) 1812 | '>' [reduce using rule 71 (primary_bool)] 1813 | SMALLEREQUAL reduce using rule 65 (primary_int) 1814 | SMALLEREQUAL [reduce using rule 71 (primary_bool)] 1815 | GREATEREQUAL reduce using rule 65 (primary_int) 1816 | GREATEREQUAL [reduce using rule 71 (primary_bool)] 1817 | IF reduce using rule 65 (primary_int) 1818 | IF [reduce using rule 67 (primary_double)] 1819 | IF [reduce using rule 69 (primary_string)] 1820 | IF [reduce using rule 71 (primary_bool)] 1821 | WHILE reduce using rule 65 (primary_int) 1822 | WHILE [reduce using rule 67 (primary_double)] 1823 | WHILE [reduce using rule 69 (primary_string)] 1824 | WHILE [reduce using rule 71 (primary_bool)] 1825 | '}' reduce using rule 65 (primary_int) 1826 | '}' [reduce using rule 67 (primary_double)] 1827 | '}' [reduce using rule 69 (primary_string)] 1828 | '}' [reduce using rule 71 (primary_bool)] 1829 | $default reduce using rule 65 (primary_int) 1830 | 1831 | 1832 | state 98 1833 | 1834 | 30 expr_int: expr_int . '+' expr_int 1835 | 31 | expr_int . '-' expr_int 1836 | 32 | expr_int . '*' expr_int 1837 | 33 | expr_int . '/' expr_int 1838 | 41 expr_string: expr_string '+' expr_int . 1839 | 1840 | '*' shift, and go to state 52 1841 | '/' shift, and go to state 53 1842 | 1843 | $default reduce using rule 41 (expr_string) 1844 | 1845 | 1846 | state 99 1847 | 1848 | 35 expr_double: expr_double . '+' expr_double 1849 | 36 | expr_double . '-' expr_double 1850 | 37 | expr_double . '*' expr_double 1851 | 38 | expr_double . '/' expr_double 1852 | 42 expr_string: expr_string '+' expr_double . 1853 | 1854 | '*' shift, and go to state 56 1855 | '/' shift, and go to state 57 1856 | 1857 | $default reduce using rule 42 (expr_string) 1858 | 1859 | 1860 | state 100 1861 | 1862 | 40 expr_string: expr_string . '+' expr_string 1863 | 40 | expr_string '+' expr_string . 1864 | 41 | expr_string . '+' expr_int 1865 | 42 | expr_string . '+' expr_double 1866 | 43 | expr_string . '+' expr_bool 1867 | 1868 | $default reduce using rule 40 (expr_string) 1869 | 1870 | 1871 | state 101 1872 | 1873 | 43 expr_string: expr_string '+' expr_bool . 1874 | 1875 | $default reduce using rule 43 (expr_string) 1876 | 1877 | 1878 | state 102 1879 | 1880 | 52 expr_cmp_eq: primary_int EQUAL primary_int . 1881 | 1882 | $default reduce using rule 52 (expr_cmp_eq) 1883 | 1884 | 1885 | state 103 1886 | 1887 | 54 expr_cmp_noteq: primary_int NOTEQUAL primary_int . 1888 | 1889 | $default reduce using rule 54 (expr_cmp_noteq) 1890 | 1891 | 1892 | state 104 1893 | 1894 | 58 expr_cmp_smaller: primary_int '<' primary_int . 1895 | 1896 | $default reduce using rule 58 (expr_cmp_smaller) 1897 | 1898 | 1899 | state 105 1900 | 1901 | 56 expr_cmp_greater: primary_int '>' primary_int . 1902 | 1903 | $default reduce using rule 56 (expr_cmp_greater) 1904 | 1905 | 1906 | state 106 1907 | 1908 | 62 expr_cmp_smallerequal: primary_int SMALLEREQUAL primary_int . 1909 | 1910 | $default reduce using rule 62 (expr_cmp_smallerequal) 1911 | 1912 | 1913 | state 107 1914 | 1915 | 60 expr_cmp_greaterequal: primary_int GREATEREQUAL primary_int . 1916 | 1917 | $default reduce using rule 60 (expr_cmp_greaterequal) 1918 | 1919 | 1920 | state 108 1921 | 1922 | 71 primary_bool: NAME . 1923 | 1924 | $default reduce using rule 71 (primary_bool) 1925 | 1926 | 1927 | state 109 1928 | 1929 | 53 expr_cmp_eq: primary_bool EQUAL primary_bool . 1930 | 1931 | $default reduce using rule 53 (expr_cmp_eq) 1932 | 1933 | 1934 | state 110 1935 | 1936 | 55 expr_cmp_noteq: primary_bool NOTEQUAL primary_bool . 1937 | 1938 | $default reduce using rule 55 (expr_cmp_noteq) 1939 | 1940 | 1941 | state 111 1942 | 1943 | 59 expr_cmp_smaller: primary_bool '<' primary_bool . 1944 | 1945 | $default reduce using rule 59 (expr_cmp_smaller) 1946 | 1947 | 1948 | state 112 1949 | 1950 | 57 expr_cmp_greater: primary_bool '>' primary_bool . 1951 | 1952 | $default reduce using rule 57 (expr_cmp_greater) 1953 | 1954 | 1955 | state 113 1956 | 1957 | 63 expr_cmp_smallerequal: primary_bool SMALLEREQUAL primary_bool . 1958 | 1959 | $default reduce using rule 63 (expr_cmp_smallerequal) 1960 | 1961 | 1962 | state 114 1963 | 1964 | 61 expr_cmp_greaterequal: primary_bool GREATEREQUAL primary_bool . 1965 | 1966 | $default reduce using rule 61 (expr_cmp_greaterequal) 1967 | 1968 | 1969 | state 115 1970 | 1971 | 26 call_func: NAME '(' set_var ')' . 1972 | 1973 | $default reduce using rule 26 (call_func) 1974 | 1975 | 1976 | state 116 1977 | 1978 | 28 expr_print: PRINT '(' stmt ')' . 1979 | 1980 | $default reduce using rule 28 (expr_print) 1981 | 1982 | 1983 | state 117 1984 | 1985 | 29 expr_print: PRINT '(' expr ')' . 1986 | 1987 | $default reduce using rule 29 (expr_print) 1988 | 1989 | 1990 | state 118 1991 | 1992 | 11 def_func: FUNCTION NAME '(' ')' . TYPE_LITERAL '{' stmt '}' 1993 | 1994 | TYPE_LITERAL shift, and go to state 122 1995 | 1996 | 1997 | state 119 1998 | 1999 | 10 def_func: FUNCTION NAME '(' def_var . ')' TYPE_LITERAL '{' stmt '}' 2000 | 2001 | ')' shift, and go to state 123 2002 | 2003 | 2004 | state 120 2005 | 2006 | 9 stmt: stmt . stmt 2007 | 14 if_stmt: IF expr_bool '{' stmt . '}' ELSE '{' stmt '}' 2008 | 2009 | DOUBLE_LITERAL shift, and go to state 1 2010 | INT_LITERAL shift, and go to state 2 2011 | BOOL_LITERAL shift, and go to state 3 2012 | STRING_LITERAL shift, and go to state 4 2013 | NAME shift, and go to state 5 2014 | PRINT shift, and go to state 6 2015 | VAR shift, and go to state 7 2016 | FUNCTION shift, and go to state 8 2017 | IF shift, and go to state 9 2018 | WHILE shift, and go to state 10 2019 | '}' shift, and go to state 124 2020 | 2021 | stmt go to state 45 2022 | def_func go to state 13 2023 | def_var go to state 14 2024 | set_var go to state 15 2025 | if_stmt go to state 16 2026 | while_stmt go to state 17 2027 | expr go to state 18 2028 | call_func go to state 19 2029 | expr_print go to state 20 2030 | expr_int go to state 21 2031 | expr_double go to state 22 2032 | expr_string go to state 23 2033 | expr_bool go to state 24 2034 | expr_cmp_eq go to state 25 2035 | expr_cmp_noteq go to state 26 2036 | expr_cmp_greater go to state 27 2037 | expr_cmp_smaller go to state 28 2038 | expr_cmp_greaterequal go to state 29 2039 | expr_cmp_smallerequal go to state 30 2040 | primary_int go to state 31 2041 | primary_double go to state 32 2042 | primary_string go to state 33 2043 | primary_bool go to state 34 2044 | 2045 | 2046 | state 121 2047 | 2048 | 9 stmt: stmt . stmt 2049 | 15 while_stmt: WHILE expr_bool '{' stmt . '}' 2050 | 2051 | DOUBLE_LITERAL shift, and go to state 1 2052 | INT_LITERAL shift, and go to state 2 2053 | BOOL_LITERAL shift, and go to state 3 2054 | STRING_LITERAL shift, and go to state 4 2055 | NAME shift, and go to state 5 2056 | PRINT shift, and go to state 6 2057 | VAR shift, and go to state 7 2058 | FUNCTION shift, and go to state 8 2059 | IF shift, and go to state 9 2060 | WHILE shift, and go to state 10 2061 | '}' shift, and go to state 125 2062 | 2063 | stmt go to state 45 2064 | def_func go to state 13 2065 | def_var go to state 14 2066 | set_var go to state 15 2067 | if_stmt go to state 16 2068 | while_stmt go to state 17 2069 | expr go to state 18 2070 | call_func go to state 19 2071 | expr_print go to state 20 2072 | expr_int go to state 21 2073 | expr_double go to state 22 2074 | expr_string go to state 23 2075 | expr_bool go to state 24 2076 | expr_cmp_eq go to state 25 2077 | expr_cmp_noteq go to state 26 2078 | expr_cmp_greater go to state 27 2079 | expr_cmp_smaller go to state 28 2080 | expr_cmp_greaterequal go to state 29 2081 | expr_cmp_smallerequal go to state 30 2082 | primary_int go to state 31 2083 | primary_double go to state 32 2084 | primary_string go to state 33 2085 | primary_bool go to state 34 2086 | 2087 | 2088 | state 122 2089 | 2090 | 11 def_func: FUNCTION NAME '(' ')' TYPE_LITERAL . '{' stmt '}' 2091 | 2092 | '{' shift, and go to state 126 2093 | 2094 | 2095 | state 123 2096 | 2097 | 10 def_func: FUNCTION NAME '(' def_var ')' . TYPE_LITERAL '{' stmt '}' 2098 | 2099 | TYPE_LITERAL shift, and go to state 127 2100 | 2101 | 2102 | state 124 2103 | 2104 | 14 if_stmt: IF expr_bool '{' stmt '}' . ELSE '{' stmt '}' 2105 | 2106 | ELSE shift, and go to state 128 2107 | 2108 | 2109 | state 125 2110 | 2111 | 15 while_stmt: WHILE expr_bool '{' stmt '}' . 2112 | 2113 | $default reduce using rule 15 (while_stmt) 2114 | 2115 | 2116 | state 126 2117 | 2118 | 11 def_func: FUNCTION NAME '(' ')' TYPE_LITERAL '{' . stmt '}' 2119 | 2120 | DOUBLE_LITERAL shift, and go to state 1 2121 | INT_LITERAL shift, and go to state 2 2122 | BOOL_LITERAL shift, and go to state 3 2123 | STRING_LITERAL shift, and go to state 4 2124 | NAME shift, and go to state 5 2125 | PRINT shift, and go to state 6 2126 | VAR shift, and go to state 7 2127 | FUNCTION shift, and go to state 8 2128 | IF shift, and go to state 9 2129 | WHILE shift, and go to state 10 2130 | 2131 | stmt go to state 129 2132 | def_func go to state 13 2133 | def_var go to state 14 2134 | set_var go to state 15 2135 | if_stmt go to state 16 2136 | while_stmt go to state 17 2137 | expr go to state 18 2138 | call_func go to state 19 2139 | expr_print go to state 20 2140 | expr_int go to state 21 2141 | expr_double go to state 22 2142 | expr_string go to state 23 2143 | expr_bool go to state 24 2144 | expr_cmp_eq go to state 25 2145 | expr_cmp_noteq go to state 26 2146 | expr_cmp_greater go to state 27 2147 | expr_cmp_smaller go to state 28 2148 | expr_cmp_greaterequal go to state 29 2149 | expr_cmp_smallerequal go to state 30 2150 | primary_int go to state 31 2151 | primary_double go to state 32 2152 | primary_string go to state 33 2153 | primary_bool go to state 34 2154 | 2155 | 2156 | state 127 2157 | 2158 | 10 def_func: FUNCTION NAME '(' def_var ')' TYPE_LITERAL . '{' stmt '}' 2159 | 2160 | '{' shift, and go to state 130 2161 | 2162 | 2163 | state 128 2164 | 2165 | 14 if_stmt: IF expr_bool '{' stmt '}' ELSE . '{' stmt '}' 2166 | 2167 | '{' shift, and go to state 131 2168 | 2169 | 2170 | state 129 2171 | 2172 | 9 stmt: stmt . stmt 2173 | 11 def_func: FUNCTION NAME '(' ')' TYPE_LITERAL '{' stmt . '}' 2174 | 2175 | DOUBLE_LITERAL shift, and go to state 1 2176 | INT_LITERAL shift, and go to state 2 2177 | BOOL_LITERAL shift, and go to state 3 2178 | STRING_LITERAL shift, and go to state 4 2179 | NAME shift, and go to state 5 2180 | PRINT shift, and go to state 6 2181 | VAR shift, and go to state 7 2182 | FUNCTION shift, and go to state 8 2183 | IF shift, and go to state 9 2184 | WHILE shift, and go to state 10 2185 | '}' shift, and go to state 132 2186 | 2187 | stmt go to state 45 2188 | def_func go to state 13 2189 | def_var go to state 14 2190 | set_var go to state 15 2191 | if_stmt go to state 16 2192 | while_stmt go to state 17 2193 | expr go to state 18 2194 | call_func go to state 19 2195 | expr_print go to state 20 2196 | expr_int go to state 21 2197 | expr_double go to state 22 2198 | expr_string go to state 23 2199 | expr_bool go to state 24 2200 | expr_cmp_eq go to state 25 2201 | expr_cmp_noteq go to state 26 2202 | expr_cmp_greater go to state 27 2203 | expr_cmp_smaller go to state 28 2204 | expr_cmp_greaterequal go to state 29 2205 | expr_cmp_smallerequal go to state 30 2206 | primary_int go to state 31 2207 | primary_double go to state 32 2208 | primary_string go to state 33 2209 | primary_bool go to state 34 2210 | 2211 | 2212 | state 130 2213 | 2214 | 10 def_func: FUNCTION NAME '(' def_var ')' TYPE_LITERAL '{' . stmt '}' 2215 | 2216 | DOUBLE_LITERAL shift, and go to state 1 2217 | INT_LITERAL shift, and go to state 2 2218 | BOOL_LITERAL shift, and go to state 3 2219 | STRING_LITERAL shift, and go to state 4 2220 | NAME shift, and go to state 5 2221 | PRINT shift, and go to state 6 2222 | VAR shift, and go to state 7 2223 | FUNCTION shift, and go to state 8 2224 | IF shift, and go to state 9 2225 | WHILE shift, and go to state 10 2226 | 2227 | stmt go to state 133 2228 | def_func go to state 13 2229 | def_var go to state 14 2230 | set_var go to state 15 2231 | if_stmt go to state 16 2232 | while_stmt go to state 17 2233 | expr go to state 18 2234 | call_func go to state 19 2235 | expr_print go to state 20 2236 | expr_int go to state 21 2237 | expr_double go to state 22 2238 | expr_string go to state 23 2239 | expr_bool go to state 24 2240 | expr_cmp_eq go to state 25 2241 | expr_cmp_noteq go to state 26 2242 | expr_cmp_greater go to state 27 2243 | expr_cmp_smaller go to state 28 2244 | expr_cmp_greaterequal go to state 29 2245 | expr_cmp_smallerequal go to state 30 2246 | primary_int go to state 31 2247 | primary_double go to state 32 2248 | primary_string go to state 33 2249 | primary_bool go to state 34 2250 | 2251 | 2252 | state 131 2253 | 2254 | 14 if_stmt: IF expr_bool '{' stmt '}' ELSE '{' . stmt '}' 2255 | 2256 | DOUBLE_LITERAL shift, and go to state 1 2257 | INT_LITERAL shift, and go to state 2 2258 | BOOL_LITERAL shift, and go to state 3 2259 | STRING_LITERAL shift, and go to state 4 2260 | NAME shift, and go to state 5 2261 | PRINT shift, and go to state 6 2262 | VAR shift, and go to state 7 2263 | FUNCTION shift, and go to state 8 2264 | IF shift, and go to state 9 2265 | WHILE shift, and go to state 10 2266 | 2267 | stmt go to state 134 2268 | def_func go to state 13 2269 | def_var go to state 14 2270 | set_var go to state 15 2271 | if_stmt go to state 16 2272 | while_stmt go to state 17 2273 | expr go to state 18 2274 | call_func go to state 19 2275 | expr_print go to state 20 2276 | expr_int go to state 21 2277 | expr_double go to state 22 2278 | expr_string go to state 23 2279 | expr_bool go to state 24 2280 | expr_cmp_eq go to state 25 2281 | expr_cmp_noteq go to state 26 2282 | expr_cmp_greater go to state 27 2283 | expr_cmp_smaller go to state 28 2284 | expr_cmp_greaterequal go to state 29 2285 | expr_cmp_smallerequal go to state 30 2286 | primary_int go to state 31 2287 | primary_double go to state 32 2288 | primary_string go to state 33 2289 | primary_bool go to state 34 2290 | 2291 | 2292 | state 132 2293 | 2294 | 11 def_func: FUNCTION NAME '(' ')' TYPE_LITERAL '{' stmt '}' . 2295 | 2296 | $default reduce using rule 11 (def_func) 2297 | 2298 | 2299 | state 133 2300 | 2301 | 9 stmt: stmt . stmt 2302 | 10 def_func: FUNCTION NAME '(' def_var ')' TYPE_LITERAL '{' stmt . '}' 2303 | 2304 | DOUBLE_LITERAL shift, and go to state 1 2305 | INT_LITERAL shift, and go to state 2 2306 | BOOL_LITERAL shift, and go to state 3 2307 | STRING_LITERAL shift, and go to state 4 2308 | NAME shift, and go to state 5 2309 | PRINT shift, and go to state 6 2310 | VAR shift, and go to state 7 2311 | FUNCTION shift, and go to state 8 2312 | IF shift, and go to state 9 2313 | WHILE shift, and go to state 10 2314 | '}' shift, and go to state 135 2315 | 2316 | stmt go to state 45 2317 | def_func go to state 13 2318 | def_var go to state 14 2319 | set_var go to state 15 2320 | if_stmt go to state 16 2321 | while_stmt go to state 17 2322 | expr go to state 18 2323 | call_func go to state 19 2324 | expr_print go to state 20 2325 | expr_int go to state 21 2326 | expr_double go to state 22 2327 | expr_string go to state 23 2328 | expr_bool go to state 24 2329 | expr_cmp_eq go to state 25 2330 | expr_cmp_noteq go to state 26 2331 | expr_cmp_greater go to state 27 2332 | expr_cmp_smaller go to state 28 2333 | expr_cmp_greaterequal go to state 29 2334 | expr_cmp_smallerequal go to state 30 2335 | primary_int go to state 31 2336 | primary_double go to state 32 2337 | primary_string go to state 33 2338 | primary_bool go to state 34 2339 | 2340 | 2341 | state 134 2342 | 2343 | 9 stmt: stmt . stmt 2344 | 14 if_stmt: IF expr_bool '{' stmt '}' ELSE '{' stmt . '}' 2345 | 2346 | DOUBLE_LITERAL shift, and go to state 1 2347 | INT_LITERAL shift, and go to state 2 2348 | BOOL_LITERAL shift, and go to state 3 2349 | STRING_LITERAL shift, and go to state 4 2350 | NAME shift, and go to state 5 2351 | PRINT shift, and go to state 6 2352 | VAR shift, and go to state 7 2353 | FUNCTION shift, and go to state 8 2354 | IF shift, and go to state 9 2355 | WHILE shift, and go to state 10 2356 | '}' shift, and go to state 136 2357 | 2358 | stmt go to state 45 2359 | def_func go to state 13 2360 | def_var go to state 14 2361 | set_var go to state 15 2362 | if_stmt go to state 16 2363 | while_stmt go to state 17 2364 | expr go to state 18 2365 | call_func go to state 19 2366 | expr_print go to state 20 2367 | expr_int go to state 21 2368 | expr_double go to state 22 2369 | expr_string go to state 23 2370 | expr_bool go to state 24 2371 | expr_cmp_eq go to state 25 2372 | expr_cmp_noteq go to state 26 2373 | expr_cmp_greater go to state 27 2374 | expr_cmp_smaller go to state 28 2375 | expr_cmp_greaterequal go to state 29 2376 | expr_cmp_smallerequal go to state 30 2377 | primary_int go to state 31 2378 | primary_double go to state 32 2379 | primary_string go to state 33 2380 | primary_bool go to state 34 2381 | 2382 | 2383 | state 135 2384 | 2385 | 10 def_func: FUNCTION NAME '(' def_var ')' TYPE_LITERAL '{' stmt '}' . 2386 | 2387 | $default reduce using rule 10 (def_func) 2388 | 2389 | 2390 | state 136 2391 | 2392 | 14 if_stmt: IF expr_bool '{' stmt '}' ELSE '{' stmt '}' . 2393 | 2394 | $default reduce using rule 14 (if_stmt) 2395 | --------------------------------------------------------------------------------