aboutsummaryrefslogtreecommitdiff
path: root/bootstrap
diff options
context:
space:
mode:
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/ast.c27
-rw-r--r--bootstrap/compiler.h8
-rw-r--r--bootstrap/outdecl.c11
-rw-r--r--bootstrap/parsedecl.c30
-rw-r--r--bootstrap/parsestmt.c4
-rw-r--r--bootstrap/typechk.c2
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(&current_funcparams, VAR_DECL_ONLY, nextptr);
+ var = parse_var(&current_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(&current_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(&current_scope->vars, vartype, nextptr_vardecl);
+ var = parse_var(&current_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
};