require ("fmt")
provide (main)
-let const_true bool = true;
-let const_false bool = false;
-let const_uint int = 123;
-let const_string string = "";
+let const_true bool = true
+let const_false bool = false
+let const_uint int = 123
+let const_string string = ""
-var var_true bool = true;
-var var_false bool = false;
-var var_uint int = 123;
-var var_string string = "";
+var var_true bool = true
+var var_false bool = false
+var var_uint int = 123
+var var_string string = ""
-type type_int = int;
-type type_intary = int[];
-type type_intaryary = int[][];
-type type_intptrary = int*[];
-type type_intptr = int*;
-type type_intptrptr = int**;
+type type_int = int
+type type_intary = int[]
+type type_intaryary = int[][]
+type type_intptrary = int*[]
+type type_intptr = int*
+type type_intptrptr = int**
type type_struct = struct {
- foo = int;
- bar = float;
-};
+ foo = int
+ bar = float
+}
type type_union = union {
- foo = int;
- bar = float;
-};
+ foo = int
+ bar = float
+}
fun main(args string[]) int {
- let foo int = 123;
- var bar int = 123;
- {}
- {123;}
- 123;
- (123);
- foo();
- bar(1);
- baz(1,2);
- if (123) {}
- if 123 {}
- if (123) {} else {}
- if (123) {} else if (123) {}
- if (123) {} else if (123) {} else {}
- if 123 {} else if 123 {} else {}
- return bar;
+ let foo int = 123
+ var bar int = 123
+ {123}
+ 123
+ (123)
+ foo()
+ bar(1)
+ baz(1,2)
+# if (123) {}
+# if 123 {}
+# if (123) {} else {}
+# if (123) {} else if (123) {}
+# if (123) {} else if (123) {} else {}
+# if 123 {} else if 123 {} else {}
+#
+# fun main(args string[]) int {
+# 123
+# }
}
static void require_list(Parser* p);
static void provide_list(Parser* p);
static AST* definition_list(Parser* p);
-static AST* const_definition(Parser* p, bool constant);
+static AST* definition(Parser* p);
static AST* type_definition(Parser* p);
static AST* func_definition(Parser* p);
+static AST* expression(Parser* p);
+static AST* constant(Parser* p);
static AST* type_expression(Parser* p);
static AST* struct_fields(Parser* p);
static AST* expression_block(Parser* p);
-static AST* statement(Parser* p);
-static AST* expression(Parser* p);
-static AST* definition(Parser* p, bool constant);
-static AST* return_statement(Parser* p);
-static AST* if_statement(Parser* p);
-static AST* func_expr_list(Parser* p);
-
-static AST* const_expression(Parser* p);
+static AST* if_expression(Parser* p);
static AST* identifier(Parser* p);
-static AST* function(Parser* p);
-static AST* literal(Parser* p);
-static AST* expr_block(Parser* p);
-static AST* if_stmnt(Parser* p);
-static AST* func_app(Parser* p, AST* fn);
+static AST* func_expr_list(Parser* p);
+static Type* get_typedef(Parser* p, char* typename);
+static AST* add_type(Parser* p, AST* ast, char* typename);
static AST* token_to_tree(Parser* p, Tok* tok);
/* Parsing Routines
static AST* definition_list(Parser* p) {
while (!matches(p, T_END_FILE)) {
- TokType type = peek(p)->type;
if (matches(p, T_LET) || matches(p, T_VAR)) {
- const_definition(p, (type == T_LET));
+ definition(p);
} else if (matches(p, T_TYPE)) {
type_definition(p);
} else if (matches(p, T_FUN)) {
func_definition(p);
} else {
- error(p, "only definitions are allowed at the toplevel");
+ error(p, "only definitions are allowed at the top level");
}
}
return NULL;
}
-static AST* const_definition(Parser* p, bool constant) {
+static AST* definition(Parser* p) {
if (!accept(p, T_LET) && !accept(p, T_VAR))
error(p, "constant or variable definition expected");
expect(p, T_ID);
type_expression(p);
expect(p, '=');
- const_expression(p);
- expect(p, ';');
+ expression(p);
return NULL;
}
expect(p, T_ID);
expect(p, '=');
type_expression(p);
- expect(p, ';');
return NULL;
}
return NULL;
}
-static AST* const_expression(Parser* p) {
- AST* expr = NULL;
- if (accept(p, '(')) {
- expr = const_expression(p);
+static AST* expression(Parser* p) {
+ if (matches(p, '(')) {
+ expect(p, '(');
+ expression(p);
expect(p, ')');
+ } else if (matches(p, '{')) {
+ expression_block(p);
+ } else if (matches(p, T_IF)) {
+ if_expression(p);
} else if (matches(p, T_ID)) {
- expr = identifier(p);
+ identifier(p);
+ if (matches(p, '('))
+ func_expr_list(p);
} else {
- expr = literal(p);
+ constant(p);
}
- return expr;
+ return NULL;
}
+static AST* constant(Parser* p) {
+ AST* ret = NULL;
+ Tok* tok = peek(p);
+ switch (tok->type) {
+ case T_BOOL:
+ case T_CHAR:
+ case T_STRING:
+ case T_INT:
+ case T_FLOAT:
+ ret = token_to_tree(p, tok);
+ tok->type = T_NONE;
+ break;
+ default:
+ error(p, "expected an expression");
+ }
+ return ret;
+}
+
+/* Type Expressions
+ ****************************************************************************/
static AST* type_expression(Parser* p) {
if (matches(p, T_STRUCT)) {
expect(p, T_STRUCT);
expect(p, T_ID);
expect(p, '=');
type_expression(p);
- expect(p, ';');
} while (!matches(p, '}'));
expect(p, '}');
return NULL;
}
+/* Expression Blocks
+ ****************************************************************************/
static AST* expression_block(Parser* p) {
expect(p, '{');
while (!matches(p, '}')) {
- statement(p);
- }
- expect(p, '}');
- return NULL;
-}
-
-static AST* statement(Parser* p) {
- if (matches(p, '{')) {
- expression_block(p);
- } else {
if (matches(p, T_LET) || matches(p, T_VAR)) {
- definition(p, (peek(p)->type == T_LET));
- } else if (matches(p, T_RETURN)) {
- return_statement(p);
- } else if (matches(p, T_IF)) {
- if_statement(p);
-// } else if (matches(p, T_WHILE)) {
-// } else if (matches(p, T_FOR)) {
-// } else if (matches(p, T_DO)) {
-// } else if (matches(p, T_SWITCH)) {
-// } else if (matches(p, T_MATCH)) {
+ definition(p);
} else {
expression(p);
- expect(p, ';');
}
}
+ expect(p, '}');
return NULL;
}
-static AST* expression(Parser* p) {
- AST* expr = NULL;
- if (accept(p, '(')) {
- expr = expression(p);
- expect(p, ')');
- } else if (matches(p, T_ID)) {
- expr = identifier(p);
- if (matches(p, '('))
- func_expr_list(p);
- } else {
- expr = literal(p);
+static AST* if_expression(Parser* p) {
+ expect(p, T_IF);
+ expression(p); // condition
+ expression(p); // true branch
+ if (accept(p, T_ELSE)) {
+ expression(p); // false branch
}
- return expr;
-}
-
-static AST* definition(Parser* p, bool constant) {
- if (!accept(p, T_LET) && !accept(p, T_VAR))
- error(p, "constant or variable definition expected");
- expect(p, T_ID);
- type_expression(p);
- expect(p, '=');
- expression(p);
- expect(p, ';');
return NULL;
}
-static AST* return_statement(Parser* p) {
- expect(p, T_RETURN);
- expression(p);
- expect(p, ';');
- return NULL;
-}
-
-static AST* if_statement(Parser* p) {
- expect(p, T_IF);
- expression(p);
- expression_block(p);
- if (accept(p, T_ELSE)) {
- if (matches(p, T_IF)) {
- if_statement(p);
- } else {
- expression_block(p);
- }
+static AST* identifier(Parser* p) {
+ Tok* tok = peek(p);
+ if (tok->type == T_ID) {
+ AST* ast = Ident(tok);
+ tok->type = T_NONE;
+ return ast;
+ } else {
+ error(p, "Expected an identifier");
+ return NULL;
}
- return NULL;
}
static AST* func_expr_list(Parser* p) {
return NULL;
}
-
-
+/* Helper Functions for Constants
+ ****************************************************************************/
static Type* get_typedef(Parser* p, char* typename) {
Sym* sym = sym_get(&(p->syms), typename);
if (!sym) error(p, "unknown type '%s'", typename);
return sym->type;
}
-static AST* literal(Parser* p) {
- AST* ret = NULL;
- Tok* tok = peek(p);
- switch (tok->type) {
- case T_BOOL:
- case T_CHAR:
- case T_STRING:
- case T_INT:
- case T_FLOAT:
- ret = token_to_tree(p, tok);
- tok->type = T_NONE;
- break;
- default:
- error(p, "expected an expression");
- }
- return ret;
-}
-
static AST* add_type(Parser* p, AST* ast, char* typename) {
ast->datatype = get_typedef(p, typename);
return ast;
}
}
-static AST* identifier(Parser* p) {
- Tok* tok = peek(p);
- if (tok->type == T_ID) {
- AST* ast = Ident(tok);
- tok->type = T_NONE;
- return ast;
- } else {
- error(p, "Expected an identifier");
- return NULL;
- }
-}