diff options
Diffstat (limited to 'bootstrap')
-rw-r--r-- | bootstrap/ast.c | 27 | ||||
-rw-r--r-- | bootstrap/compiler.h | 8 | ||||
-rw-r--r-- | bootstrap/outdecl.c | 11 | ||||
-rw-r--r-- | bootstrap/parsedecl.c | 30 | ||||
-rw-r--r-- | bootstrap/parsestmt.c | 4 | ||||
-rw-r--r-- | bootstrap/typechk.c | 2 |
6 files changed, 68 insertions, 14 deletions
diff --git a/bootstrap/ast.c b/bootstrap/ast.c index ea73e1e..034c11e 100644 --- a/bootstrap/ast.c +++ b/bootstrap/ast.c @@ -17,6 +17,8 @@ struct Func *current_func; static struct Type **type_nextptr, **inner_type_nextptr; static struct Func **func_nextptr; static struct Func **type_func_nextptr, **innertype_func_nextptr; +static struct Var **var_nextptr; +static struct Var **type_var_nextptr, **innertype_var_nextptr; void module_start(void) { @@ -61,6 +63,8 @@ struct Type *map_named_type(const char *name, size_t len) t->funcs_list = NULL; t->inner_types = NULL; t->inner_types_list = NULL; + t->vars = NULL; + t->vars_list = NULL; t->next = NULL; if (current_type) { *inner_type_nextptr = t; @@ -91,8 +95,10 @@ void type_start(const char *name, size_t len) t->ident.node.is_defined = true; if (current_type) { innertype_func_nextptr = &t->funcs_list; + innertype_var_nextptr = &t->vars_list; } else { type_func_nextptr = &t->funcs_list; + type_var_nextptr = &t->vars_list; inner_type_nextptr = &t->inner_types_list; } current_type = t; @@ -101,6 +107,12 @@ void type_start(const char *name, size_t len) void type_end(void) { current_type = current_type->outer; + innertype_func_nextptr = NULL; + innertype_var_nextptr = NULL; + if (!current_type) { + type_func_nextptr = NULL; + type_var_nextptr = NULL; + } } struct Func *map_named_func(const char *name, size_t len) @@ -155,3 +167,18 @@ void func_end(void) { current_func = NULL; } + +void toplevel_var_add(struct Var *var) +{ + struct Var ***nextptr; + if (current_type && current_type->outer) { + nextptr = &innertype_var_nextptr; + } else if (current_type) { + nextptr = &type_var_nextptr; + } else { + nextptr = &var_nextptr; + } + var->next = NULL; + **nextptr = var; + *nextptr = &var->next; +} diff --git a/bootstrap/compiler.h b/bootstrap/compiler.h index b5fd9a2..d44ab45 100644 --- a/bootstrap/compiler.h +++ b/bootstrap/compiler.h @@ -143,7 +143,9 @@ struct Type { struct Func *funcs_list; struct TreeNode *inner_types; struct Type *inner_types_list; - /* TODO flags, fields, ... */ + struct TreeNode *vars; + struct Var *vars_list; + /* TODO flags? i.e. what can be done with the type */ struct Type *next; }; @@ -405,6 +407,7 @@ void type_end(void); struct Func *map_named_func(const char *name, size_t len); void func_start(const char *name, size_t len); void func_end(void); +void toplevel_var_add(struct Var *var); void srcloc_init(struct SourceLocation *srcloc); /* ======================================================================= @@ -433,8 +436,7 @@ enum VarType { void parse_func_body(void); struct Expr *parse_expr(void); -struct Var *parse_var(struct TreeNode **root, enum VarType vartype, - struct Var **list_out); +struct Var *parse_var(struct TreeNode **root, enum VarType vartype); struct Var *lookup_local_var(const char *name, size_t len); /** Reports an error in the source code and exits */ NORETURN void error(const char *s); diff --git a/bootstrap/outdecl.c b/bootstrap/outdecl.c index 799a49c..138464b 100644 --- a/bootstrap/outdecl.c +++ b/bootstrap/outdecl.c @@ -111,6 +111,8 @@ void predeclare_type(struct Type *type) void define_type(struct Type *type) { + struct Var *field; + if (!type->ident.node.is_defined) { /* TODO distinguish betwen opaque and missing types */ return; @@ -118,13 +120,14 @@ void define_type(struct Type *type) set_srcloc(&type->ident.srcloc); outc('\n'); emit_type(type); - outf(" {\n"); - indentlevel++; - /* TODO for each field + beginf(" {\n"); + for (field = type->vars_list; field; field = field->next) { + indent(); emit_typeref_prefix(field->typeref); emit_ident(&field->ident); emit_typeref_suffix(field->typeref); - */ + outf(";\n"); + } endf("};\n"); clear_srcloc(); } diff --git a/bootstrap/parsedecl.c b/bootstrap/parsedecl.c index bd8edb0..29cb2dd 100644 --- a/bootstrap/parsedecl.c +++ b/bootstrap/parsedecl.c @@ -17,6 +17,7 @@ struct TreeNode *current_funcparams = NULL; static void parse_func(void); static enum Token parse_paramlist(struct Var **list_out, size_t *count_out); +static void parse_instance_variable(void); static struct TypeRef *parse_type_usage(void); static const struct TypeRefNumeric range_uint = { @@ -346,6 +347,18 @@ void parse_file(FILE *f, const char *basename) or allow it, and have imports go into namespaces? */ parse_func(); break; + TOKEN_CASES_QUALIFIERS + case T_KW_bool: + case T_KW_byte: + case T_KW_int: + case T_KW_long: + case T_UpperIdent: + /* Instance variable definition */ + /* TODO disallow modifiable variables (or variables of modifiable + types) inside non-class (utility) files */ + unread_token(); + parse_instance_variable(); + break; /* TODO more top-level keywords */ default: error("Unexpected token at top level"); @@ -449,7 +462,9 @@ static enum Token parse_paramlist(struct Var **list_out, size_t *count_out) } unread_token(); - var = parse_var(¤t_funcparams, VAR_DECL_ONLY, nextptr); + var = parse_var(¤t_funcparams, VAR_DECL_ONLY); + assert(*nextptr == NULL); + *nextptr = var; nextptr = &var->next; var->is_funcparam = 1; expect_next_line(); @@ -460,6 +475,13 @@ static enum Token parse_paramlist(struct Var **list_out, size_t *count_out) } } +static void parse_instance_variable(void) +{ + struct Var *var = parse_var(¤t_type->vars, VAR_ALLOW_INITVAL); + var->is_funcparam = 1; + toplevel_var_add(var); +} + /* TODO parsing of type decls. this needs to handle: - both top-level and nested types struct Type **inspoint; @@ -578,8 +600,7 @@ static struct TypeRef *parse_type_usage(void) return tr; } -struct Var *parse_var(struct TreeNode **root, enum VarType vartype, - struct Var **list_out) +struct Var *parse_var(struct TreeNode **root, enum VarType vartype) { struct LexemeInfo li; enum Token t; @@ -621,8 +642,5 @@ struct Var *parse_var(struct TreeNode **root, enum VarType vartype, } else { unread_token(); } - - assert(*list_out == NULL); - *list_out = var; return var; } diff --git a/bootstrap/parsestmt.c b/bootstrap/parsestmt.c index 053b1c4..bb90389 100644 --- a/bootstrap/parsestmt.c +++ b/bootstrap/parsestmt.c @@ -343,11 +343,13 @@ static struct Var *parse_local_var(enum VarType vartype) struct Var *var; /* TODO disallow defining the same name with different types in different scopes? */ - var = parse_var(¤t_scope->vars, vartype, nextptr_vardecl); + var = parse_var(¤t_scope->vars, vartype); if (exists_in_outer_scope(var)) { error("Name shadows an existing variable name in an outer scope"); } var->is_funcparam = 0; + assert(*nextptr_vardecl == NULL); + *nextptr_vardecl = var; nextptr_vardecl = &var->next; return var; } diff --git a/bootstrap/typechk.c b/bootstrap/typechk.c index 99c14d3..ad6ef30 100644 --- a/bootstrap/typechk.c +++ b/bootstrap/typechk.c @@ -30,6 +30,8 @@ static struct Type builtin_string_class = { /* funcs_list = */ NULL /* TODO */, /* inner_types = */ NULL, /* inner_types_list = */ NULL, + /* vars = */ NULL, + /* vars_list = */ NULL, /* next = */ NULL }; |