diff options
Diffstat (limited to 'src/parser.y')
| -rw-r--r-- | src/parser.y | 174 |
1 files changed, 128 insertions, 46 deletions
diff --git a/src/parser.y b/src/parser.y index 776e1c9..bd5b033 100644 --- a/src/parser.y +++ b/src/parser.y @@ -191,12 +191,17 @@ static char match_escape(char c); */ static char *strip(const char *s); +#define Q(x) if (!(x)) { YYABORT; } + %} %start input; %% param - : type ID { $$ = gen_var($2, $1, src_loc(@$)); } + : type ID { + $$ = gen_var($2, $1, src_loc(@$)); + Q($$); + } rev_params : rev_params "," param { $$ = $3; $$->n = $1; } @@ -214,7 +219,10 @@ opt_params var : param - | ID { $$ = gen_var($1, NULL, src_loc(@$)); } + | ID { + $$ = gen_var($1, NULL, src_loc(@$)); + Q($$); + } rev_vars : rev_vars "," var { $$ = $3; $$->n = $1; } @@ -231,52 +239,60 @@ opt_vars proc : ID "(" opt_params ")" body { $$ = gen_proc($[ID], $[opt_params], NULL, $[body], src_loc(@$)); + Q($$); } proc_decl : ID "(" opt_params ")" ";" { $$ = gen_proc($[ID], $[opt_params], NULL, NULL, src_loc(@$)); + Q($$); } binop - : expr "+" expr { $$ = gen_binop(AST_ADD, $1, $3, src_loc(@$)); } - | expr "-" expr { $$ = gen_binop(AST_SUB, $1, $3, src_loc(@$)); } - | expr "*" expr { $$ = gen_binop(AST_MUL, $1, $3, src_loc(@$)); } - | expr "/" expr { $$ = gen_binop(AST_DIV, $1, $3, src_loc(@$)); } - | expr "%" expr { $$ = gen_binop(AST_REM, $1, $3, src_loc(@$)); } - | expr "<" expr { $$ = gen_comparison(AST_LT, $1, $3, src_loc(@$)); } - | expr ">" expr { $$ = gen_comparison(AST_GT, $1, $3, src_loc(@$)); } - | expr "<<" expr { $$ = gen_binop(AST_LSHIFT, $1, $3, src_loc(@$)); } - | expr ">>" expr { $$ = gen_binop(AST_RSHIFT, $1, $3, src_loc(@$)); } - | expr "<=" expr { $$ = gen_comparison(AST_LE, $1, $3, src_loc(@$)); } - | 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(@$)); } + : expr "+" expr { $$ = gen_binop(AST_ADD, $1, $3, src_loc(@$)); Q($$); } + | expr "-" expr { $$ = gen_binop(AST_SUB, $1, $3, src_loc(@$)); Q($$); } + | expr "*" expr { $$ = gen_binop(AST_MUL, $1, $3, src_loc(@$)); Q($$); } + | expr "/" expr { $$ = gen_binop(AST_DIV, $1, $3, src_loc(@$)); Q($$); } + | expr "%" expr { $$ = gen_binop(AST_REM, $1, $3, src_loc(@$)); Q($$); } + | expr "<" expr { $$ = gen_comparison(AST_LT, $1, $3, src_loc(@$)); Q($$); } + | expr ">" expr { $$ = gen_comparison(AST_GT, $1, $3, src_loc(@$)); Q($$); } + | expr "<<" expr { $$ = gen_binop(AST_LSHIFT, $1, $3, src_loc(@$)); Q($$); } + | expr ">>" expr { $$ = gen_binop(AST_RSHIFT, $1, $3, src_loc(@$)); Q($$); } + | expr "<=" expr { $$ = gen_comparison(AST_LE, $1, $3, src_loc(@$)); Q($$); } + | expr ">=" expr { $$ = gen_comparison(AST_GE, $1, $3, src_loc(@$)); Q($$); } + | expr "!=" expr { $$ = gen_comparison(AST_NE, $1, $3, src_loc(@$)); Q($$); } + | expr "==" expr { $$ = gen_comparison(AST_EQ, $1, $3, src_loc(@$)); Q($$); } + | id "~" id { $$ = gen_paste($1, $3, src_loc(@$)); Q($$); } unop - : "-" expr { $$ = gen_unop(AST_NEG, $2, src_loc(@$)); } - | "!" expr { $$ = gen_unop(AST_LNOT, $2, src_loc(@$)); } - | "~" expr { $$ = gen_unop(AST_BNEG, $2, src_loc(@$)); } + : "-" expr { $$ = gen_unop(AST_NEG, $2, src_loc(@$)); Q($$); } + | "!" expr { $$ = gen_unop(AST_LNOT, $2, src_loc(@$)); Q($$); } + | "~" expr { $$ = gen_unop(AST_BNEG, $2, src_loc(@$)); Q($$); } type - : ID { $$ = tgen_id($1, src_loc(@$)); } - | "(" opt_types ")" { $$ = tgen_closure($2, src_loc(@$)); } + : ID { + $$ = tgen_id($1, src_loc(@$)); + Q($$); + } + | "(" opt_types ")" { $$ = tgen_closure($2, src_loc(@$)); Q($$); } | "&&" type { if ($2->k == TYPE_CLOSURE) { $$ = $2; $$->k = TYPE_PURE_CLOSURE; } else { $$ = tgen_ref($2, src_loc(@$)); + Q($$); } /* heh */ $$ = tgen_ref($$, src_loc(@$)); + Q($$); } | "&" type { if ($2->k == TYPE_CLOSURE) { $$ = $2; $$->k = TYPE_PURE_CLOSURE; } else { $$ = tgen_ref($2, src_loc(@$)); + Q($$); } } | "*" type { @@ -284,6 +300,7 @@ type $$ = $2; $$->k = TYPE_FUNC_PTR; } else { $$ = tgen_ptr($2, src_loc(@$)); + Q($$); } } @@ -302,6 +319,7 @@ opt_types construction : expr "=>" ID { $$ = gen_construction($3, $1, src_loc(@$)); + Q($$); } constructions @@ -315,6 +333,7 @@ opt_constructions deconstruction : ID "=>" var { $$ = gen_deconstruction($1, $3, src_loc(@$)); + Q($$); } deconstructions @@ -328,23 +347,33 @@ opt_deconstructions construct : "[" opt_constructions "]" ID { $$ = gen_construct($4, $2, src_loc(@$)); + Q($$); } id - : ID { $$ = gen_id($1, src_loc(@$)); } + : ID { + $$ = gen_id($1, src_loc(@$)); + Q($$); + } expr - : "sizeof" "(" type ")" { $$ = gen_sizeof($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(@$)); } - | "*" { $$ = gen_nil(src_loc(@$)); } + : "sizeof" "(" type ")" { $$ = gen_sizeof($3, src_loc(@$)); Q($$); } + | STRING { + char *s = strip($1); + Q(s); + + $$ = gen_const_str(s, src_loc(@$)); + Q($$); + } + | FLOAT { $$ = gen_const_float($1, src_loc(@$)); Q($$); } + | BOOL { $$ = gen_const_bool($1, src_loc(@$)); Q($$); } + | CHAR { $$ = gen_const_char($1, src_loc(@$)); Q($$); } + | INT { $$ = gen_const_int($1, src_loc(@$)); Q($$); } + | "*" { $$ = gen_nil(src_loc(@$)); Q($$); } | "(" expr ")" { $$ = $2; } - | expr "&" { $$ = gen_ref($1, src_loc(@$)); } - | expr "*" { $$ = gen_deref($1, src_loc(@$)); } - | expr "as" type { $$ = gen_as($1, $3, src_loc(@$)); } + | expr "&" { $$ = gen_ref($1, src_loc(@$)); Q($$); } + | expr "*" { $$ = gen_deref($1, src_loc(@$)); Q($$); } + | expr "as" type { $$ = gen_as($1, $3, src_loc(@$)); Q($$); } | construct | id | binop @@ -364,9 +393,11 @@ opt_exprs closure : "=>" opt_vars body { $$ = gen_closure($[opt_vars], $[body], src_loc(@$)); + Q($$); } | "&" "=>" opt_vars body { $$ = gen_closure($[opt_vars], $[body], src_loc(@$)); + Q($$); ast_set_flags($$, AST_FLAG_NOMOVES); } @@ -375,9 +406,13 @@ rev_closures | closure trailing_closure - : "=>" opt_vars ";" { $$ = gen_closure($[opt_vars], NULL, src_loc(@$));} + : "=>" opt_vars ";" { + $$ = gen_closure($[opt_vars], NULL, src_loc(@$)); + Q($$); + } | "&" "=>" opt_vars ";" { $$ = gen_closure($[opt_vars], NULL, src_loc(@$)); + Q($$); ast_set_flags($$, AST_FLAG_NOMOVES); } @@ -398,46 +433,66 @@ closures call : expr "(" opt_exprs ")" { $$ = gen_call($1, $[opt_exprs], src_loc(@$)); + Q($$); } | expr "(" opt_exprs ")" "=>" opt_vars ";" { /* the rest of the function body is our closure, gets fixed up * later */ struct ast *closure = gen_closure($[opt_vars], NULL, src_loc(@$)); + Q(closure); + ast_append(&$[opt_exprs], closure); $$ = gen_call($[expr], $[opt_exprs], src_loc(@$)); + Q($$); } | expr "(" opt_exprs ")" closures { ast_append(&$[opt_exprs], $[closures]); $$ = gen_call($[expr], $[opt_exprs], src_loc(@$)); + Q($$); } put - : put "*" { $$ = gen_put($1, src_loc(@$)); } - | id "*" { $$ = gen_put($1, src_loc(@$)); } + : put "*" { $$ = gen_put($1, src_loc(@$)); Q($$); } + | id "*" { $$ = gen_put($1, src_loc(@$)); Q($$); } let - : expr "=>" var ";" { $$ = gen_let($3, $1, src_loc(@$)); } - | expr "=>" put ";" { $$ = gen_write($3, $1, src_loc(@$)); } + : expr "=>" var ";" { + $$ = gen_let($3, $1, src_loc(@$)); + Q($$); + } + | expr "=>" put ";" { + $$ = gen_write($3, $1, src_loc(@$)); + Q($$); + } explode : expr "=>" "[" opt_deconstructions "]" { $$ = gen_explode($4, $1, src_loc(@$)); + Q($$); } if - : "if" expr body "else" body { $$ = gen_if($2, $3, $5, src_loc(@$)); } - | "if" expr body "else" if { $$ = gen_if($2, $3, $5, src_loc(@$)); } + : "if" expr body "else" body { + $$ = gen_if($2, $3, $5, src_loc(@$)); + Q($$); + } + | "if" expr body "else" if { + $$ = gen_if($2, $3, $5, src_loc(@$)); + Q($$); + } nil : "nil" expr body "=>" var ";" { /** @todo should nil check define new scope for created * variable? */ $$ = gen_nil_check($2, $3, $5, src_loc(@$)); + Q($$); } forget : "nil" ID ";" { $$ = gen_forget($2, src_loc(@$)); + Q($$); } statement @@ -448,7 +503,7 @@ statement | let | nil | if - | ";" { $$ = gen_empty(src_loc(@$)); } + | ";" { $$ = gen_empty(src_loc(@$)); Q($$); } rev_statements : rev_statements statement { $$ = $2; $2->n = $1; } @@ -467,6 +522,7 @@ opt_statements body : "{" opt_statements "}" { $$ = gen_block($2, src_loc(@$)); + Q($$); } behaviour @@ -483,7 +539,10 @@ opt_behaviours | { $$ = NULL; } impl - : ID "!" { $$ = gen_implements($1, src_loc(@$)); } + : ID "!" { + $$ = gen_implements($1, src_loc(@$)); + Q($$); + } member : param @@ -499,7 +558,10 @@ opt_members type_param : ID ID { struct type *t = tgen_id($1, src_loc(@1)); + Q(t); + $$ = gen_var($2, t, src_loc(@$)); + Q($$); } type_params @@ -532,38 +594,50 @@ opt_elements template : ID "[" opt_type_params "]" "(" opt_vars ")" "{" opt_elements "}" { $$ = gen_template($1, $3, $6, $9, src_loc(@$)); + Q($$); } 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(@$)); + Q(pseudoinst); + $$ = gen_supertemplate($1, $3, $6, pseudoinst, $17, src_loc(@$)); + Q($$); } struct : ID "{" opt_members "}" { $$ = gen_struct($1, $3, src_loc(@$)); + Q($$); } struct_cont : "continue" ID "{" opt_behaviours "}" { $$ = gen_instance_cont($2, $4, src_loc(@$)); + Q($$); } trait : ID "=" "{" opt_behaviours "}" { $$ = gen_trait($1, $4, src_loc(@$)); + Q($$); } instance : ID "=" id "[" opt_types "]" "(" opt_exprs ")" { $$ = gen_instance($1, $3, $5, $8, src_loc(@$)); + Q($$); } import : "import" STRING { - $$ = gen_import(strip($2), src_loc(@$)); + char *s = strip($2); + Q(s); + + $$ = gen_import(s, src_loc(@$)); + Q($$); } top @@ -585,6 +659,8 @@ top | "pub" supertemplate { $$ = $2; ast_set_flags($$, AST_FLAG_PUBLIC); } | error { $$ = gen_empty(src_loc(@$)); + Q($$); + parser->failed = true; /* ignore any content inside a top level thing and just move onto * the next one */ @@ -679,11 +755,11 @@ static char match_escape(char c) static char *strip(const char *str) { const size_t len = strlen(str) + 1; - char *buf = malloc(len); + char *buf = mallocc(len); if (!buf) { /* should probably try to handle the error in some way... */ internal_error("failed allocating buffer for string clone"); - free((void *)str); + /* str should be in tracker already, so no need to free it */ return NULL; } @@ -693,14 +769,20 @@ static char *strip(const char *str) buf[j++] = str[i]; buf[j] = 0; - free((void *)str); + track_ptr(buf); return buf; } struct parser *create_parser() { - return calloc(1, sizeof(struct parser)); + struct parser *p = callocc(1, sizeof(struct parser)); + if (!p) { + internal_error("failed allocating parser"); + return NULL; + } + + return p; } void destroy_parser(struct parser *p) |
