Code cleanup for KeywordArg
This commit is contained in:
parent
197da905f5
commit
9aec32149f
7
ast.c
7
ast.c
@ -57,8 +57,8 @@ CORD arg_list_to_cord(arg_ast_t *args) {
|
||||
c = CORD_cat(c, args->name);
|
||||
if (args->type)
|
||||
CORD_sprintf(&c, "%r:%r", c, type_ast_to_cord(args->type));
|
||||
if (args->default_val)
|
||||
CORD_sprintf(&c, "%r=%r", c, ast_to_cord(args->default_val));
|
||||
if (args->value)
|
||||
CORD_sprintf(&c, "%r=%r", c, ast_to_cord(args->value));
|
||||
if (args->next) c = CORD_cat(c, ", ");
|
||||
}
|
||||
return CORD_cat(c, ")");
|
||||
@ -119,8 +119,7 @@ CORD ast_to_cord(ast_t *ast)
|
||||
T(FunctionDef, "(name=%r, args=%r, ret=%r, body=%r)", ast_to_cord(data.name),
|
||||
arg_list_to_cord(data.args), type_ast_to_cord(data.ret_type), ast_to_cord(data.body))
|
||||
T(Lambda, "(args=%r, body=%r)", arg_list_to_cord(data.args), ast_to_cord(data.body))
|
||||
T(FunctionCall, "(fn=%r, args=%r)", ast_to_cord(data.fn), ast_list_to_cord(data.args))
|
||||
T(KeywordArg, "(%s=%r)", ast_to_cord(data.arg))
|
||||
T(FunctionCall, "(fn=%r, args=%r)", ast_to_cord(data.fn), arg_list_to_cord(data.args))
|
||||
T(Block, "(%r)", ast_list_to_cord(data.statements))
|
||||
T(For, "(index=%r, value=%r, iter=%r, body=%r)", ast_to_cord(data.index), ast_to_cord(data.value),
|
||||
ast_to_cord(data.iter), ast_to_cord(data.body))
|
||||
|
10
ast.h
10
ast.h
@ -32,7 +32,7 @@ typedef struct when_clause_s {
|
||||
typedef struct arg_ast_s {
|
||||
const char *name;
|
||||
type_ast_t *type;
|
||||
ast_t *default_val;
|
||||
ast_t *value;
|
||||
struct arg_ast_s *next;
|
||||
} arg_ast_t;
|
||||
|
||||
@ -97,7 +97,7 @@ typedef enum {
|
||||
Min, Max,
|
||||
Array, Table, TableEntry,
|
||||
FunctionDef, Lambda,
|
||||
FunctionCall, KeywordArg,
|
||||
FunctionCall,
|
||||
Block,
|
||||
For, While, If, When,
|
||||
Reduction,
|
||||
@ -185,13 +185,9 @@ struct ast_s {
|
||||
} Lambda;
|
||||
struct {
|
||||
ast_t *fn;
|
||||
ast_list_t *args;
|
||||
arg_ast_t *args;
|
||||
type_ast_t *extern_return_type;
|
||||
} FunctionCall;
|
||||
struct {
|
||||
const char *name;
|
||||
ast_t *arg;
|
||||
} KeywordArg;
|
||||
struct {
|
||||
ast_list_t *statements;
|
||||
} Block;
|
||||
|
22
compile.c
22
compile.c
@ -524,7 +524,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
CORD name = compile(env, fndef->name);
|
||||
CORD_appendf(&env->code->staticdefs, "static %r %r_(", fndef->ret_type ? compile_type_ast(fndef->ret_type) : "void", name);
|
||||
for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) {
|
||||
type_t *arg_type = arg->type ? parse_type_ast(env, arg->type) : get_type(env, arg->default_val);
|
||||
type_t *arg_type = arg->type ? parse_type_ast(env, arg->type) : get_type(env, arg->value);
|
||||
CORD_appendf(&env->code->staticdefs, "%r %s", compile_type(arg_type), arg->name);
|
||||
if (arg->next) env->code->staticdefs = CORD_cat(env->code->staticdefs, ", ");
|
||||
}
|
||||
@ -536,7 +536,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
env_t *body_scope = fresh_scope(env);
|
||||
body_scope->locals->fallback = env->globals;
|
||||
for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) {
|
||||
type_t *arg_type = arg->type ? parse_type_ast(env, arg->type) : get_type(env, arg->default_val);
|
||||
type_t *arg_type = arg->type ? parse_type_ast(env, arg->type) : get_type(env, arg->value);
|
||||
CORD arg_typecode = compile_type(arg_type);
|
||||
CORD_appendf(&env->code->funcs, "%r %s", arg_typecode, arg->name);
|
||||
if (arg->next) env->code->funcs = CORD_cat(env->code->funcs, ", ");
|
||||
@ -565,12 +565,12 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
// Pass 2: assign positional args
|
||||
// Pass 3: compile and typecheck each arg
|
||||
table_t arg_bindings = {};
|
||||
for (ast_list_t *arg = call->args; arg; arg = arg->next) {
|
||||
if (arg->ast->tag == KeywordArg)
|
||||
Table_str_set(&arg_bindings, Match(arg->ast, KeywordArg)->name, Match(arg->ast, KeywordArg)->arg);
|
||||
for (arg_ast_t *arg = call->args; arg; arg = arg->next) {
|
||||
if (arg->name)
|
||||
Table_str_set(&arg_bindings, arg->name, arg->value);
|
||||
}
|
||||
for (ast_list_t *call_arg = call->args; call_arg; call_arg = call_arg->next) {
|
||||
if (call_arg->ast->tag == KeywordArg)
|
||||
for (arg_ast_t *call_arg = call->args; call_arg; call_arg = call_arg->next) {
|
||||
if (call_arg->name)
|
||||
continue;
|
||||
|
||||
const char *name = NULL;
|
||||
@ -581,9 +581,9 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
}
|
||||
}
|
||||
if (name)
|
||||
Table_str_set(&arg_bindings, name, call_arg->ast);
|
||||
Table_str_set(&arg_bindings, name, call_arg->value);
|
||||
else
|
||||
code_err(call_arg->ast, "This is too many arguments to the function: %T", fn_t);
|
||||
code_err(call_arg->value, "This is too many arguments to the function: %T", fn_t);
|
||||
}
|
||||
|
||||
// TODO: ensure args get executed in order (e.g. `foo(y=get_next(1), x=get_next(2))`
|
||||
@ -612,10 +612,6 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
return CORD_cat_char(code, ')');
|
||||
}
|
||||
// Lambda,
|
||||
case KeywordArg: {
|
||||
auto kwarg = Match(ast, KeywordArg);
|
||||
return CORD_asprintf(".%s=%r", kwarg->name, compile(env, kwarg->arg));
|
||||
}
|
||||
case If: {
|
||||
auto if_ = Match(ast, If);
|
||||
CORD code;
|
||||
|
28
parse.c
28
parse.c
@ -1172,31 +1172,21 @@ ast_t *parse_fncall_suffix(parse_ctx_t *ctx, ast_t *fn, bool is_extern) {
|
||||
|
||||
whitespace(&pos);
|
||||
|
||||
ast_list_t *args = NULL;
|
||||
arg_ast_t *args = NULL;
|
||||
for (;;) {
|
||||
const char *arg_start = pos;
|
||||
const char *name = get_id(&pos);
|
||||
whitespace(&pos);
|
||||
if (name) {
|
||||
if (match(&pos, "=")) {
|
||||
whitespace(&pos);
|
||||
ast_t *arg = parse_expr(ctx, pos);
|
||||
if (!arg) parser_err(ctx, arg_start, pos, "I couldn't parse this keyword argument value");
|
||||
ast_t *kwarg = NewAST(ctx->file, arg_start, arg->end, KeywordArg,
|
||||
.name=name, .arg=arg);
|
||||
args = new(ast_list_t, .ast=kwarg, .next=args);
|
||||
pos = kwarg->end;
|
||||
goto got_arg;
|
||||
}
|
||||
if (!name || !match(&pos, "="))
|
||||
pos = arg_start;
|
||||
}
|
||||
|
||||
ast_t *arg = optional(ctx, &pos, parse_expr);
|
||||
if (!arg) break;
|
||||
args = new(ast_list_t, .ast=arg, .next=args);
|
||||
|
||||
got_arg:;
|
||||
|
||||
if (!arg) {
|
||||
if (name)
|
||||
parser_err(ctx, arg_start, pos, "I expected an argument here");
|
||||
break;
|
||||
}
|
||||
args = new(arg_ast_t, .name=name, .value=arg, .next=args);
|
||||
if (!match_separator(&pos))
|
||||
break;
|
||||
}
|
||||
@ -1634,7 +1624,7 @@ arg_ast_t *parse_args(parse_ctx_t *ctx, const char **pos, bool allow_unnamed)
|
||||
|
||||
REVERSE_LIST(names);
|
||||
for (; names; names = names->next)
|
||||
args = new(arg_ast_t, .name=names->name, .type=type, .default_val=default_val, .next=args);
|
||||
args = new(arg_ast_t, .name=names->name, .type=type, .value=default_val, .next=args);
|
||||
|
||||
if (!match_separator(pos))
|
||||
break;
|
||||
|
17
typecheck.c
17
typecheck.c
@ -62,8 +62,8 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast)
|
||||
if (arg->type) {
|
||||
type_args->type = parse_type_ast(env, arg->type);
|
||||
} else {
|
||||
type_args->default_val = arg->default_val;
|
||||
type_args->type = get_type(env, arg->default_val);
|
||||
type_args->default_val = arg->value;
|
||||
type_args->type = get_type(env, arg->value);
|
||||
}
|
||||
}
|
||||
REVERSE_LIST(type_args);
|
||||
@ -114,7 +114,7 @@ void bind_statement(env_t *env, ast_t *statement)
|
||||
type_t *type = Type(StructType, .name=def->name, .fields=fields); // placeholder
|
||||
for (arg_ast_t *field_ast = def->fields; field_ast; field_ast = field_ast->next) {
|
||||
type_t *field_t = parse_type_ast(env, field_ast->type);
|
||||
fields = new(arg_t, .name=field_ast->name, .type=field_t, .default_val=field_ast->default_val, .next=fields);
|
||||
fields = new(arg_t, .name=field_ast->name, .type=field_t, .default_val=field_ast->value, .next=fields);
|
||||
}
|
||||
REVERSE_LIST(fields);
|
||||
type->__data.StructType.fields = fields; // populate placeholder
|
||||
@ -134,7 +134,7 @@ void bind_statement(env_t *env, ast_t *statement)
|
||||
arg_t *fields = NULL;
|
||||
for (arg_ast_t *field_ast = tag_ast->fields; field_ast; field_ast = field_ast->next) {
|
||||
type_t *field_t = parse_type_ast(env, field_ast->type);
|
||||
fields = new(arg_t, .name=field_ast->name, .type=field_t, .default_val=field_ast->default_val, .next=fields);
|
||||
fields = new(arg_t, .name=field_ast->name, .type=field_t, .default_val=field_ast->value, .next=fields);
|
||||
}
|
||||
REVERSE_LIST(fields);
|
||||
type_t *tag_type = Type(StructType, .name=heap_strf("%s$%s", def->name, tag_ast->name), .fields=fields);
|
||||
@ -160,8 +160,8 @@ type_t *get_function_def_type(env_t *env, ast_t *ast)
|
||||
arg_t *args = NULL;
|
||||
env_t *scope = fresh_scope(env);
|
||||
for (arg_ast_t *arg = fn->args; arg; arg = arg->next) {
|
||||
type_t *t = arg->type ? parse_type_ast(env, arg->type) : get_type(env, arg->default_val);
|
||||
args = new(arg_t, .name=arg->name, .type=t, .default_val=arg->default_val, .next=args);
|
||||
type_t *t = arg->type ? parse_type_ast(env, arg->type) : get_type(env, arg->value);
|
||||
args = new(arg_t, .name=arg->name, .type=t, .default_val=arg->value, .next=args);
|
||||
set_binding(scope, arg->name, new(binding_t, .type=t));
|
||||
}
|
||||
REVERSE_LIST(args);
|
||||
@ -327,9 +327,6 @@ type_t *get_type(env_t *env, ast_t *ast)
|
||||
}
|
||||
}
|
||||
}
|
||||
case KeywordArg: {
|
||||
return get_type(env, Match(ast, KeywordArg)->arg);
|
||||
}
|
||||
case FunctionCall: {
|
||||
auto call = Match(ast, FunctionCall);
|
||||
if (call->extern_return_type)
|
||||
@ -514,7 +511,7 @@ type_t *get_type(env_t *env, ast_t *ast)
|
||||
arg_t *args = NULL;
|
||||
env_t *scope = fresh_scope(env);
|
||||
for (arg_ast_t *arg = lambda->args; arg; arg = arg->next) {
|
||||
type_t *t = arg->type ? parse_type_ast(env, arg->type) : get_type(env, arg->default_val);
|
||||
type_t *t = arg->type ? parse_type_ast(env, arg->type) : get_type(env, arg->value);
|
||||
args = new(arg_t, .name=arg->name, .type=t, .next=args);
|
||||
set_binding(scope, arg->name, new(binding_t, .type=t));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user