Simplify code by making name := use ...
a Use AST instead of a Declare
This commit is contained in:
parent
9b15799e73
commit
ca93e6f3cb
2
ast.c
2
ast.c
@ -156,7 +156,7 @@ CORD ast_to_xml(ast_t *ast)
|
||||
T(Optional, "<Optional>%r</Optional>", ast_to_xml(data.value))
|
||||
T(NonOptional, "<NonOptional>%r</NonOptional>", ast_to_xml(data.value))
|
||||
T(DocTest, "<DocTest>%r<output>%r</output></DocTest>", optional_tagged("expression", data.expr), xml_escape(data.output))
|
||||
T(Use, "<Use>%r</Use>", xml_escape(data.path))
|
||||
T(Use, "<Use>%r%r</Use>", optional_tagged("var", data.var), xml_escape(data.path))
|
||||
T(InlineCCode, "<InlineCode>%r</InlineCode>", xml_escape(data.code))
|
||||
default: return "???";
|
||||
#undef T
|
||||
|
1
ast.h
1
ast.h
@ -311,6 +311,7 @@ struct ast_s {
|
||||
bool skip_source:1;
|
||||
} DocTest;
|
||||
struct {
|
||||
ast_t *var;
|
||||
const char *path;
|
||||
enum { USE_LOCAL, USE_MODULE, USE_SHARED_OBJECT, USE_HEADER, USE_C_CODE, USE_ASM } what;
|
||||
} Use;
|
||||
|
13
compile.c
13
compile.c
@ -569,9 +569,7 @@ CORD compile_statement(env_t *env, ast_t *ast)
|
||||
}
|
||||
case Declare: {
|
||||
auto decl = Match(ast, Declare);
|
||||
if (decl->value->tag == Use) {
|
||||
return compile_statement(env, decl->value);
|
||||
} else if (streq(Match(decl->var, Var)->name, "_")) { // Explicit discard
|
||||
if (streq(Match(decl->var, Var)->name, "_")) { // Explicit discard
|
||||
return CORD_all("(void)", compile(env, decl->value), ";");
|
||||
} else {
|
||||
type_t *t = get_type(env, decl->value);
|
||||
@ -3584,7 +3582,7 @@ CORD compile_file(env_t *env, ast_t *ast)
|
||||
type_t *t = get_type(env, decl->value);
|
||||
if (t->tag == AbortType || t->tag == VoidType || t->tag == ReturnType)
|
||||
code_err(stmt->ast, "You can't declare a variable with a %T value", t);
|
||||
if (!(decl->value->tag == Use || is_constant(env, decl->value))) {
|
||||
if (!is_constant(env, decl->value)) {
|
||||
CORD val_code = compile_maybe_incref(env, decl->value);
|
||||
if (t->tag == FunctionType) {
|
||||
assert(promote(env, &val_code, t, Type(ClosureType, t)));
|
||||
@ -3609,9 +3607,7 @@ CORD compile_file(env_t *env, ast_t *ast)
|
||||
CORD full_name = CORD_all(namespace_prefix(env, env->namespace), decl_name);
|
||||
bool is_private = (decl_name[0] == '_');
|
||||
type_t *t = get_type(env, decl->value);
|
||||
if (decl->value->tag == Use) {
|
||||
assert(compile_statement(env, stmt->ast) == CORD_EMPTY);
|
||||
} else if (!is_constant(env, decl->value)) {
|
||||
if (!is_constant(env, decl->value)) {
|
||||
env->code->staticdefs = CORD_all(
|
||||
env->code->staticdefs,
|
||||
"static bool ", full_name, "$initialized = false;\n",
|
||||
@ -3665,9 +3661,6 @@ CORD compile_statement_header(env_t *env, ast_t *ast)
|
||||
switch (ast->tag) {
|
||||
case Declare: {
|
||||
auto decl = Match(ast, Declare);
|
||||
if (decl->value->tag == Use)
|
||||
return compile_statement_header(env, decl->value);
|
||||
|
||||
const char *decl_name = Match(decl->var, Var)->name;
|
||||
bool is_private = (decl_name[0] == '_');
|
||||
if (is_private)
|
||||
|
28
parse.c
28
parse.c
@ -133,7 +133,6 @@ static PARSER(parse_table);
|
||||
static PARSER(parse_term);
|
||||
static PARSER(parse_term_no_suffix);
|
||||
static PARSER(parse_text);
|
||||
static PARSER(parse_top_declaration);
|
||||
static PARSER(parse_update);
|
||||
static PARSER(parse_use);
|
||||
static PARSER(parse_var);
|
||||
@ -1750,20 +1749,6 @@ PARSER(parse_declaration) {
|
||||
return NewAST(ctx->file, start, pos, Declare, .var=var, .value=val);
|
||||
}
|
||||
|
||||
PARSER(parse_top_declaration) {
|
||||
const char *start = pos;
|
||||
ast_t *var = parse_var(ctx, pos);
|
||||
if (!var) return NULL;
|
||||
pos = var->end;
|
||||
spaces(&pos);
|
||||
if (!match(&pos, ":=")) return NULL;
|
||||
spaces(&pos);
|
||||
ast_t *val = optional(ctx, &pos, parse_use);
|
||||
if (!val) val = optional(ctx, &pos, parse_extended_expr);
|
||||
if (!val) parser_err(ctx, pos, strchrnul(pos, '\n'), "This declaration value didn't parse");
|
||||
return NewAST(ctx->file, start, pos, Declare, .var=var, .value=val);
|
||||
}
|
||||
|
||||
PARSER(parse_update) {
|
||||
const char *start = pos;
|
||||
ast_t *lhs = optional(ctx, &pos, parse_expr);
|
||||
@ -1980,7 +1965,7 @@ PARSER(parse_file_body) {
|
||||
||(stmt=optional(ctx, &pos, parse_use))
|
||||
||(stmt=optional(ctx, &pos, parse_extern))
|
||||
||(stmt=optional(ctx, &pos, parse_inline_c))
|
||||
||(stmt=optional(ctx, &pos, parse_top_declaration)))
|
||||
||(stmt=optional(ctx, &pos, parse_declaration)))
|
||||
{
|
||||
statements = new(ast_list_t, .ast=stmt, .next=statements);
|
||||
pos = stmt->end;
|
||||
@ -2348,6 +2333,15 @@ PARSER(parse_say) {
|
||||
|
||||
PARSER(parse_use) {
|
||||
const char *start = pos;
|
||||
|
||||
ast_t *var = parse_var(ctx, pos);
|
||||
if (var) {
|
||||
pos = var->end;
|
||||
spaces(&pos);
|
||||
if (!match(&pos, ":=")) return NULL;
|
||||
spaces(&pos);
|
||||
}
|
||||
|
||||
if (!match_word(&pos, "use")) return NULL;
|
||||
spaces(&pos);
|
||||
size_t name_len = strcspn(pos, " \t\r\n;");
|
||||
@ -2384,7 +2378,7 @@ PARSER(parse_use) {
|
||||
name = hash;
|
||||
}
|
||||
}
|
||||
return NewAST(ctx->file, start, pos, Use, .path=name, .what=what);
|
||||
return NewAST(ctx->file, start, pos, Use, .var=var, .path=name, .what=what);
|
||||
}
|
||||
|
||||
ast_t *parse_file(const char *path, jmp_buf *on_err) {
|
||||
|
14
typecheck.c
14
typecheck.c
@ -255,11 +255,7 @@ void bind_statement(env_t *env, ast_t *statement)
|
||||
return;
|
||||
if (get_binding(env, name))
|
||||
code_err(decl->var, "A %T called '%s' has already been defined", get_binding(env, name)->type, name);
|
||||
if (decl->value->tag == Use) {
|
||||
(void)load_module(env, decl->value);
|
||||
} else {
|
||||
bind_statement(env, decl->value);
|
||||
}
|
||||
bind_statement(env, decl->value);
|
||||
type_t *type = get_type(env, decl->value);
|
||||
if (!type)
|
||||
code_err(decl->value, "I couldn't figure out the type of this value");
|
||||
@ -394,9 +390,15 @@ void bind_statement(env_t *env, ast_t *statement)
|
||||
if (Table$str_get(*env->types, entry->name))
|
||||
continue;
|
||||
|
||||
//code_err(statement, "This module imports a type called '%s', which would clobber another type", entry->name);
|
||||
Table$str_set(env->types, entry->name, entry->type);
|
||||
}
|
||||
|
||||
ast_t *var = Match(statement, Use)->var;
|
||||
if (var) {
|
||||
type_t *type = get_type(env, statement);
|
||||
assert(type);
|
||||
set_binding(env, Match(var, Var)->name, new(binding_t, .type=type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Extern: {
|
||||
|
Loading…
Reference in New Issue
Block a user