aboutsummaryrefslogtreecommitdiff
path: root/src/parser.y
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-03-24 03:16:41 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2023-03-24 03:16:41 +0200
commit3bd9103ce0b18f6900ba544a8b2786145868524f (patch)
tree235ed722d5058ee0c2bf32d7c0eabd9f581e9273 /src/parser.y
parent5b038666c3e911ffeb78a4d656044e5bd076705b (diff)
downloadek-3bd9103ce0b18f6900ba544a8b2786145868524f.tar.gz
ek-3bd9103ce0b18f6900ba544a8b2786145868524f.zip
struct initializers
Diffstat (limited to 'src/parser.y')
-rw-r--r--src/parser.y73
1 files changed, 43 insertions, 30 deletions
diff --git a/src/parser.y b/src/parser.y
index 8242c2a..1b477d6 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -111,7 +111,7 @@
%token FATARROW "=>"
/* precedence */
-%left "," "typeof" "sizeof"
+%left ","
%right "=" "+=" "-=" "*=" "/=" "%=" "<<=" ">>=" "&=" "^=" "|=" "^^="
%left "^^"
%left "||"
@@ -124,7 +124,7 @@
%left "<<" ">>"
%left "+" "-"
%left "*" "/" "%"
-%left "as"
+%left "as" "sizeof" "typeof"
%right "'" "!" "~"
%left "." "=>" "(" ")"
@@ -132,11 +132,12 @@
%nterm <node> import binary_op unary_op arg arg_list decl_list call expr
%nterm <node> while do_while statement statement_list body macro_list macro
%nterm <node> expr_list init_expr expr_if if for case case_list switch const
-%nterm <node> func_sign variadic_sign impl impl_list type var_decl var
+%nterm <node> func_sign variadic_sign type var_decl var
%nterm <node> var_init proc lambda template_elem template_list type_list
%nterm <node> type_alias type_template enum_val enum_list enum top unit id
%nterm <node> embed param_decl union union_list union_elem struct struct_list
-%nterm <node> top_if const_if const_for defer goto
+%nterm <node> top_if const_if const_for defer goto assign
+%nterm <node> struct_construct struct_inits struct_init cond
%destructor {} FLOAT INT STRING ID
%destructor { destroy_ast_tree($$); } <*>
@@ -159,8 +160,11 @@ embed: "embed" "(" STRING ")" { $$ = gen_embed(clone_string($3)); }
import: "import" STRING { $$ = gen_import(clone_string($2)); }
;
-binary_op: expr "=" expr { $$ = gen_binop(AST_ASSIGN, $1, $3); }
- | expr "+" expr { $$ = gen_binop(AST_ADD, $1, $3); }
+assign: expr "=" expr { $$ = gen_assign($1, $3); }
+ | expr "=" struct_construct { $$ = gen_assign($1, $3); }
+ ;
+
+binary_op: expr "+" expr { $$ = gen_binop(AST_ADD, $1, $3); }
| expr "-" expr { $$ = gen_binop(AST_SUB, $1, $3); }
| expr "*" expr { $$ = gen_binop(AST_MUL, $1, $3); }
| expr "/" expr { $$ = gen_binop(AST_DIV, $1, $3); }
@@ -202,7 +206,7 @@ unary_op: "-" expr { $$ = gen_unop(AST_NEG, $2); }
| "~" expr { $$ = gen_unop(AST_NOT, $2); }
;
-arg: "&" var_decl { $$ = gen_unop(SQUOTE, $2); }
+arg: "&" var_decl { $$ = gen_unop(AST_REF, $2); }
| var_decl { $$ = $1; }
| init_expr { $$ = $1; }
;
@@ -240,6 +244,7 @@ expr: id { $$ = $1; }
$$->loc = to_src_loc(&yylloc);
}
| "(" expr ")" { $$ = $2; }
+ | assign { $$ = $1; }
| call { $$ = $1; }
| defer { $$ = $1; }
| binary_op { $$ = $1; }
@@ -264,7 +269,7 @@ do_while: "do" body "while" expr ";" {
goto: "goto" id { $$ = gen_goto(gen_label($2)); }
statement: expr ";" { $$ = $1; }
- | "return" expr ";" { $$ = gen_return($2); }
+ | "return" init_expr ";" { $$ = gen_return($2); }
| "return" ";" { $$ = gen_return(NULL); }
| "break" ";" { $$ = gen_ctrl(AST_CTRL_BREAK, to_src_loc(&yylloc)); }
| "continue" ";" { $$ = gen_ctrl(AST_CTRL_CONTINUE,
@@ -335,23 +340,38 @@ expr_list: expr "," expr_list { $$ = $1; $1->next = $3; }
| expr { $$ = $1; }
;
+struct_init: init_expr { $$ = $1; }
+ | "." id "=" init_expr { $$ = gen_var($2, NULL, $4); }
+ ;
+
+struct_inits: struct_init "," struct_inits { $$ = $1; $1->next = $3; }
+ | struct_init { $$ = $1; }
+ ;
+
+struct_construct: "{" struct_inits "}" { $$ = gen_init($2); }
+ ;
+
init_expr: expr { $$ = $1; }
- | var_init { $$ = $1; }
- | "&" var_init { $$ = gen_unop(AND, $2); }
| expr_if { $$ = $1; }
+ | struct_construct { $$ = $1; }
+ | struct_construct "as" type { $$ = gen_cast($1, $3); }
+ ;
+
+cond: expr { $$ = $1; }
+ | "(" expr_if ")" { $$ = $2; }
+ /* note no struct construct */
;
-expr_if: "if" init_expr body "else" body { $$ = gen_if($2, $3, $5); }
- | "if" init_expr body "else" expr_if { $$ = gen_if($2, $3, $5); }
- ;
+expr_if: "if" cond body "else" body { $$ = gen_if($2, $3, $5); }
+ | "if" cond body "else" expr_if { $$ = gen_if($2, $3, $5); }
+ ;
-if: "if" init_expr body { $$ = gen_if($2, $3, NULL); }
- | "if" init_expr body "else" body { $$ = gen_if($2, $3, $5); }
- | "if" init_expr body "else" if { $$ = gen_if($2, $3, $5); }
+if: "if" cond body { $$ = gen_if($2, $3, NULL); }
+ | "if" cond body "else" body { $$ = gen_if($2, $3, $5); }
+ | "if" cond body "else" if { $$ = gen_if($2, $3, $5); }
;
-for: "for" arg ";" expr ";" expr body { $$ = gen_for($2, $4, $6, $7);
- }
+for: "for" arg ";" expr ";" expr body { $$ = gen_for($2, $4, $6, $7); }
;
case: "case" expr ":" statement_list { $$ = gen_case($2, $4); }
@@ -415,21 +435,12 @@ variadic_sign: func_sign { $$ = $1; }
}
;
-impl: id "{" type_list "}" { $$ = gen_type(AST_TYPE_IMPL, $1, $3, NULL);
- }
- | id { $$ = gen_type(AST_TYPE_IMPL, $1, NULL, NULL); }
- ;
-
-impl_list: impl "," impl_list { $$ = $1; $1->next = $3;}
- | impl { $$ = $1; }
- ;
-
type: id { $$ = gen_type(AST_TYPE_ID, $1, NULL, NULL); }
| "'" func_sign {
$$ = gen_type(AST_TYPE_POINTER, NULL, NULL, NULL);
$$->next = $2;
}
- | id "(" impl_list ")" {
+ | id "(" type_list ")" {
$$ = gen_type(AST_TYPE_STRUCT, $1, $3, NULL);
}
| "'" type {
@@ -504,12 +515,14 @@ struct_list: union_list { $$ = $1; }
struct: "struct" id "{" struct_list "}" {
$$ = gen_struct($2, NULL, $4);
}
- | "struct" id "(" type_list ")" "{" struct_list "}" {
+ | "struct" id "(" arg_list ")" "{" struct_list "}" {
$$ = gen_struct($2, $4, $7);
}
;
-template_elem: impl ";" { $$ = $1; }
+/* since traits aren't generic, they don't have to implement anything, meaning
+ * we can keep a pretty clean separation between procs and supertraits */
+template_elem: id ";" { $$ = $1; }
| id func_sign ";" { $$ = gen_proc($1, $2, NULL); }
| var_decl ";" { $$ = $1; }
| union { $$ = $1; }