diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-12-06 20:00:42 +0200 | 
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-12-06 20:00:42 +0200 | 
| commit | 0cef986e6958a0a6a7e94e8256b0039709aed56b (patch) | |
| tree | 54d161ff8c2028a2b7819d11b1d74f6b99d01ca3 /src | |
| parent | 1466d2d1032db1e08a4105312f000a1c284d2889 (diff) | |
| download | fwd-0cef986e6958a0a6a7e94e8256b0039709aed56b.tar.gz fwd-0cef986e6958a0a6a7e94e8256b0039709aed56b.zip | |
add trailing closures
+ Useful for guard statements, not entirely sure about the final syntax
  but at least they're possible
Diffstat (limited to 'src')
| -rw-r--r-- | src/lower.c | 17 | ||||
| -rw-r--r-- | src/parser.y | 24 | 
2 files changed, 37 insertions, 4 deletions
| diff --git a/src/lower.c b/src/lower.c index 35d16fe..4b9fae9 100644 --- a/src/lower.c +++ b/src/lower.c @@ -123,6 +123,11 @@ static int lower_type_construct(struct type *type)  static int lower_type_callable(struct type *type)  { +	/* std::function has a slight overhead compared to just using auto here, +	 * but auto doesn't play well with recursive templates like with our +	 * fib.fwd example, so use std::function for now. Eventually I might +	 * instead write a C backend or something to have more control over the +	 * exact semantics, but for now this is good enough. */  	printf("std::function<void(");  	if (lower_types(tcallable_args(type))) @@ -317,8 +322,10 @@ static int lower_if(struct state *state, struct ast *stmt)  	if (lower_block(state, if_body(stmt)))  		return -1; -	if (!if_else(stmt)) +	if (!if_else(stmt)) { +		printf("\n");  		return 0; +	}  	printf(" else ");  	if (lower_block(state, if_else(stmt))) @@ -403,6 +410,11 @@ static int lower_closure(struct state *state, struct ast *closure)  static int lower_proto(struct ast *proc)  { +	/* 'extern' functions should be provided to us by whatever framework the +	 * user is using */ +	if (!proc_body(proc)) +		return 0; +  	if (strcmp("main", proc_id(proc)) == 0)  		printf("int ");  	else @@ -419,6 +431,9 @@ static int lower_proto(struct ast *proc)  static int lower_proc(struct ast *proc)  { +	if (!proc_body(proc)) +		return 0; +  	if (strcmp("main", proc_id(proc)) == 0)  		printf("int ");  	else diff --git a/src/parser.y b/src/parser.y index 97a700e..9f532b9 100644 --- a/src/parser.y +++ b/src/parser.y @@ -93,8 +93,8 @@  %left "::"  %nterm <node> top unit proc call closure var expr statement body -%nterm <node> vars exprs statements closures -%nterm <node> opt_vars opt_exprs opt_statements +%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> let if unop binop construct @@ -197,6 +197,9 @@ proc  	: ID "(" opt_vars ")" body {  		$$ = gen_proc($[ID], $[opt_vars], NULL, $[body], src_loc(@$));  	} +	| ID "(" opt_vars ")" ";" { +		$$ = gen_proc($[ID], $[opt_vars], NULL, NULL, src_loc(@$)); +	}  binop  	: expr "+"  expr { $$ = gen_binop(AST_ADD, $1, $3, src_loc(@$));  } @@ -276,8 +279,22 @@ rev_closures  	: rev_closures closure { $$ = $2; $2->n = $1; }  	| closure +trailing_closure +	: "=>" opt_vars ";" { $$ = gen_closure($[opt_vars], NULL, src_loc(@$));} + +opt_trailing_closure +	: trailing_closure +	| { $$ = NULL; } +  closures -	: rev_closures { $$ = reverse_ast_list($1); } +	: rev_closures opt_trailing_closure { +		if ($[opt_trailing_closure]) { +			$[opt_trailing_closure]->n = $[rev_closures]; +			$$ = reverse_ast_list($[opt_trailing_closure]); +		} else { +			$$ = reverse_ast_list($[rev_closures]); +		} +	}  call  	: expr "(" opt_exprs ")" ";" { @@ -307,6 +324,7 @@ statement  	: call  	| let  	| if +	| body  	| ";" { $$ = gen_empty(src_loc(@$)); }  rev_statements | 
