diff options
Diffstat (limited to 'src/parser.y')
-rw-r--r-- | src/parser.y | 185 |
1 files changed, 141 insertions, 44 deletions
diff --git a/src/parser.y b/src/parser.y index 6ec2eb2..023c10a 100644 --- a/src/parser.y +++ b/src/parser.y @@ -36,7 +36,6 @@ %token <dbl> FLOAT %token <str> STRING %token <str> ID -%token <str> APPLY %token QUESTION "?" %token SQUOTE "'" @@ -70,6 +69,7 @@ %token RBRACE "}" %token LBRACKET "[" %token RBRACKET "]" +%token AS "as" %token IF "if" %token ELSE "else" %token NIL "nil" @@ -79,7 +79,6 @@ %token IMPORT "import" %token ERROR "error" %token DOT "." -%token SCOPE "::" %token FATARROW "=>" %right "[" "]" @@ -95,19 +94,26 @@ %left "*" "/" "%" %left "as" "sizeof" %right "'" "!" "~" +%right ".." %left "." "=>" "(" ")" -%left "::" -%nterm <node> top unit proc proc_decl call closure var expr statement body -%nterm <node> vars exprs statements closures trailing_closure -%nterm <node> opt_vars opt_exprs opt_statements opt_trailing_closure -%nterm <node> rev_vars rev_exprs rev_closures rev_statements +%nterm <node> top unit proc proc_decl call closure expr statement body +%nterm <node> exprs statements closures trailing_closure +%nterm <node> opt_exprs opt_statements opt_trailing_closure +%nterm <node> rev_exprs rev_closures rev_statements %nterm <node> let if nil unop binop construct import +%nterm <node> opt_vars vars rev_vars var +%nterm <node> opt_params params rev_params param + %nterm <node> struct struct_cont trait %nterm <node> type_param type_params opt_type_params %nterm <node> behaviour behaviours opt_behaviours %nterm <node> member members opt_members +%nterm <node> opt_elements elements rev_elements element +%nterm <node> instance template supertemplate +%nterm <node> opt_constructions constructions construction +%nterm <node> id impl forget assign %nterm <type> type rev_types types opt_types @@ -189,12 +195,29 @@ static char *strip(const char *s); %start input; %% -var +param : type ID { $$ = gen_var($2, $1, src_loc(@$)); } +rev_params + : rev_params "," param { $$ = $3; $$->n = $1; } + | rev_params "|" param { $$ = $3; $$->n = $1; opt_group($1, $3); } + | param + +params + : rev_params { $$ = reverse_ast_list($1); } + | rev_params "," { $$ = reverse_ast_list($1); } + +opt_params + : params + | {$$ = NULL;} + + +var + : param + | ID { $$ = gen_var($1, NULL, src_loc(@$)); } + rev_vars : rev_vars "," var { $$ = $3; $$->n = $1; } - | rev_vars "|" var { $$ = $3; $$->n = $1; opt_group($1, $3); } | var vars @@ -206,13 +229,13 @@ opt_vars | {$$ = NULL;} proc - : ID "(" opt_vars ")" body { - $$ = gen_proc($[ID], $[opt_vars], NULL, $[body], src_loc(@$)); + : ID "(" opt_params ")" body { + $$ = gen_proc($[ID], $[opt_params], NULL, $[body], src_loc(@$)); } proc_decl - : ID "(" opt_vars ")" ";" { - $$ = gen_proc($[ID], $[opt_vars], NULL, NULL, src_loc(@$)); + : ID "(" opt_params ")" ";" { + $$ = gen_proc($[ID], $[opt_params], NULL, NULL, src_loc(@$)); } binop @@ -229,17 +252,20 @@ binop | expr ">=" expr { $$ = gen_comparison(AST_GE, $1, $3, src_loc(@$)); } | expr "!=" expr { $$ = gen_comparison(AST_NE, $1, $3, src_loc(@$)); } | expr "==" expr { $$ = gen_comparison(AST_EQ, $1, $3, src_loc(@$)); } + | id "~" id { $$ = gen_paste($1, $3, src_loc(@$)); } unop : "-" expr { $$ = gen_unop(AST_NEG, $2, src_loc(@$)); } - | "!" expr { $$ = gen_unop(AST_LNOT, $2, src_loc(@$)); } + | "!" expr { $$ = gen_unop(AST_LNOT, $2, src_loc(@$)); } + | "~" expr { $$ = gen_unop(AST_BNEG, $2, src_loc(@$)); } type - : ID { $$ = tgen_id($[ID], src_loc(@$)); } - | APPLY "[" opt_types "]" { - $$ = tgen_construct($[APPLY], $[opt_types], src_loc(@$)); - } + : ID { $$ = tgen_id($1, src_loc(@$)); } | "(" opt_types ")" { $$ = tgen_closure($2, src_loc(@$)); } + | "[" "]" type { + /* TODO static sizes? */ + $$ = tgen_arr($3, NULL, src_loc(@$)); + } | "&&" type { if ($2->k == TYPE_CLOSURE) { $$ = $2; $$->k = TYPE_PURE_CLOSURE; @@ -276,26 +302,43 @@ opt_types : types | { $$ = NULL; } -construct - : APPLY "{" opt_exprs "}" { - $$ = gen_init($[APPLY], NULL, $[opt_exprs], src_loc(@$)); +construction + : expr "=>" ID { + $$ = gen_construction($3, $1, src_loc(@$)); } - | APPLY "[" opt_types "]" "{" opt_exprs "}" { - $$ = gen_init($[APPLY], $[opt_types], $[opt_exprs], src_loc(@$)); + +constructions + : constructions "," construction { $$ = $3; $$->n = $1; } + | construction + +opt_constructions + : constructions + | { $$ = NULL; } + +construct + : "(" opt_constructions ")" ID { + $$ = gen_construct($4, $2, src_loc(@$)); } +id + : ID { $$ = gen_id($1, src_loc(@$)); } + expr - : expr "." ID { $$ = gen_dot($3, $1, src_loc(@$)); } + : "sizeof" "(" type ")" { $$ = gen_sizeof($3, src_loc(@$)); } + | expr "." ID { $$ = gen_dot($3, $1, src_loc(@$)); } + | expr "[" expr "]" { $$ = gen_arr($1, $3, src_loc(@$)); } | STRING { $$ = gen_const_str(strip($1), src_loc(@$)); } | FLOAT { $$ = gen_const_float($1, src_loc(@$)); } | BOOL { $$ = gen_const_bool($1, src_loc(@$)); } | CHAR { $$ = gen_const_char($1, src_loc(@$)); } | INT { $$ = gen_const_int($1, src_loc(@$)); } - | ID { $$ = gen_id($1, src_loc(@$)); } + | "*" { $$ = gen_nil(src_loc(@$)); } | "(" expr ")" { $$ = $2; } | expr "&" { $$ = gen_ref($1, src_loc(@$)); } | expr "*" { $$ = gen_deref($1, src_loc(@$)); } + | expr "as" type { $$ = gen_as($1, $3, src_loc(@$)); } | construct + | id | binop | unop @@ -369,12 +412,24 @@ if | "if" expr body "else" if { $$ = gen_if($2, $3, $5, src_loc(@$)); } nil - : "nil" ID body "=>" var { - $$ = gen_nil($2, $3, $5, src_loc(@$)); + : "nil" expr body "=>" var ";" { + $$ = gen_nil_check($2, $3, $5, src_loc(@$)); + } + +forget + : "nil" ID ";" { + $$ = gen_forget($2, src_loc(@$)); + } + +assign + : expr "=" expr ";" { + $$ = gen_assign($1, $3, src_loc(@$)); } statement : call + | forget + | assign | body | let | nil @@ -398,9 +453,9 @@ body } behaviour - : APPLY ";" { $$ = gen_trait_apply($1, src_loc(@$)); } - | proc_decl ";" + : proc_decl | proc + | impl behaviours : behaviours behaviour { $$ = $1; $1->n = $2; } @@ -410,16 +465,18 @@ opt_behaviours : behaviours | { $$ = NULL; } +impl + : ID "!" { $$ = gen_implements($1, src_loc(@$)); } + member - : var ";" - | behaviour + : param members - : members member { $$ = $1; $1->n = $2; } + : members ";" member { $$ = $3; $$->n = $1; } | member opt_members - : members + : members ";" | { $$ = NULL; } type_param @@ -438,19 +495,53 @@ opt_type_params : type_params | { $$ = NULL; } +element + : proc + | struct + | impl + | var ";" + +rev_elements + : rev_elements element { $$ = $2; $$->n = $1; } + | element + +elements + : rev_elements { $$ = reverse_ast_list($1); } + +opt_elements + : elements + | { $$ = NULL; } + +template + : ID "[" opt_type_params "]" "(" opt_vars ")" "{" opt_elements "}" { + $$ = gen_template($1, $3, $6, $9, src_loc(@$)); + } + +supertemplate + : ID "[" opt_type_params "]" "(" opt_vars ")" "=" + id "[" opt_types "]" "(" opt_exprs ")" "{" opt_elements "}" { + struct ast *pseudoinst = gen_instance(NULL, $9, $11, $14, src_loc(@$)); + $$ = gen_supertemplate($1, $3, $6, pseudoinst, $17, src_loc(@$)); + } + struct - : ID "[" opt_type_params "]" "{" opt_members "}" { - $$ = gen_struct($1, $3, $6, src_loc(@$)); + : ID "{" opt_members "}" { + $$ = gen_struct($1, $3, src_loc(@$)); } struct_cont - : "continue" ID "[" opt_type_params "]" "{" opt_behaviours "}" { - $$ = gen_struct_cont($2, $4, $7, src_loc(@$)); + : "continue" ID "{" opt_behaviours "}" { + $$ = gen_instance_cont($2, $4, src_loc(@$)); } trait - : ID "{" opt_behaviours "}" { - $$ = gen_trait($1, $3, src_loc(@$)); + : ID "=" "{" opt_behaviours "}" { + $$ = gen_trait($1, $4, src_loc(@$)); + } + +instance + : ID "=" id "[" opt_types "]" "(" opt_exprs ")" { + $$ = gen_instance($1, $3, $5, $8, src_loc(@$)); } import @@ -464,11 +555,17 @@ top | struct_cont | import | trait - | "pub" proc { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } - | "pub" struct { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } - | "pub" struct_cont { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } - | "pub" import { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } - | "pub" trait { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } + | instance + | template + | supertemplate + | "pub" proc { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } + | "pub" struct { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } + | "pub" struct_cont { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } + | "pub" import { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } + | "pub" trait { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } + | "pub" instance { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } + | "pub" template { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } + | "pub" supertemplate { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } | error { $$ = gen_empty(src_loc(@$)); parser->failed = true; |