let const_uint int = 123;
let const_string string = "";
- var const_true bool = true;
- var const_false bool = false;
- var const_uint int = 123;
- var const_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_struct = struct;
- type type_union = union;
- # type type_intary int[]
- # type type_intary42 int[42]
- # type type_intaryary int[][]
- # type type_intptrary int*[]
- # type type_intrefary int&[]
- # type type_intptr int*
- # type type_intptrptr int**
- # type type_intref 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;
+ };
+ type type_union = union {
+ foo = int;
+ bar = float;
+ };
fun main() int {
++ let foo int = 123;
++ var bar int = 123;
++ {}
++ {123;}
++ 123;
++ (123);
++ return bar;
}
-
-
-
%%
- [ \t\r\n] { /* whitespace is insignificant */ }
- #.*[\r\n] { /* skip line comments */ }
-
- "require" { return T_REQUIRES; }
- "provide" { return T_PROVIDES; }
- "let" { return T_LET; }
- "var" { return T_VAR; }
- "fun" { return T_FUN; }
- "type" { return T_TYPE; }
- "struct" { return T_STRUCT; }
- "union" { return T_UNION; }
-
- "if" { return T_IF; }
- "else" { return T_ELSE; }
- "(" { return T_LPAR; }
- ")" { return T_RPAR; }
- "[" { return T_LBRACK; }
- "]" { return T_RBRACK; }
- "{" { return T_LBRACE; }
- "}" { return T_RBRACE; }
- "," { return T_COMMA; }
- "'" { return T_SQUOTE; }
- ":" { return T_COLON; }
- "&" { return T_AMP; }
- "=" { return T_ASSIGN; }
- ";" { return T_SEMI; }
+ "\r\n" { yylineno++; }
+ "\n" { yylineno++; }
+ #.*[\r\n] { yylineno++; }
+ [ \t] { /* whitespace is insignificant */ }
+
+ "require" { return T_REQUIRES; }
+ "provide" { return T_PROVIDES; }
+ "let" { return T_LET; }
+ "var" { return T_VAR; }
+ "fun" { return T_FUN; }
+ "type" { return T_TYPE; }
+ "struct" { return T_STRUCT; }
+ "union" { return T_UNION; }
++"return" { return T_RETURN; }
+
+ "(" { return '('; }
+ ")" { return ')'; }
+ "[" { return '['; }
+ "]" { return ']'; }
+ "{" { return '{'; }
+ "}" { return '}'; }
+ "," { return ','; }
+ "'" { return '\''; }
+ ":" { return ':'; }
+ "&" { return '&'; }
+ "=" { return '='; }
+ ";" { return ';'; }
+ "*" { return '*'; }
\\. { Value.character = yytext[1]; return T_CHAR; }
\\space { Value.character = ' '; return T_CHAR; }
static AST* type_definition(Parser* p);
static AST* func_definition(Parser* p);
static AST* type_expression(Parser* p);
- static AST* const_expression(Parser* p);
- static AST* definition(Parser* p);
+ static AST* struct_fields(Parser* p);
-static AST* const_expression(Parser* p);
-static AST* definition(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* const_expression(Parser* p);
static AST* identifier(Parser* p);
static AST* function(Parser* p);
static AST* literal(Parser* p);
static AST* func_definition(Parser* p) {
expect(p, T_FUN);
expect(p, T_ID);
- expect(p, T_LPAR);
- expect(p, T_RPAR);
+ expect(p, '(');
+ expect(p, ')');
type_expression(p);
- expect(p, T_LBRACE);
- expect(p, T_RBRACE);
- expect(p, '{');
- expect(p, '}');
++ expression_block(p);
return NULL;
}
return NULL;
}
- } while(!matches(p, '}'));
+ static AST* struct_fields(Parser* p) {
+ expect(p, '{');
+ do {
+ expect(p, T_ID);
+ expect(p, '=');
+ type_expression(p);
+ expect(p, ';');
++ } while (!matches(p, '}'));
+ expect(p, '}');
+ return NULL;
+ }
++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 (accept(p, T_RETURN)) {
++ expression(p);
++ expect(p, ';');
++ } else if (matches(p, T_LET) || matches(p, T_VAR)) {
++ definition(p, (peek(p)->type == T_LET));
++ } else {
++ expression(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);
++ } else {
++ expr = literal(p);
++ }
++ 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, '=');
++ const_expression(p);
++ expect(p, ';');
++ return NULL;
++}
fprintf(file, "%c", ' ');
}
--static const char* token_type_to_string(TokType type) {
++static const char* token_type_to_string(int type) {
switch(type) {
case T_STRING: return "T_STRING";
case T_CHAR: return "T_CHAR";
/* Token Types
*****************************************************************************/
typedef enum {
- T_NONE, T_ERROR, T_END_FILE,
+ T_NONE = 0, T_ERROR = 256, T_END_FILE,
T_PACKAGE, T_REQUIRES, T_PROVIDES, T_LET, T_VAR, T_FUN, T_TYPE, T_STRUCT,
-- T_UNION,
++ T_UNION, T_RETURN,
T_ID, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING,
- T_LBRACE, T_RBRACE, T_LBRACK, T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_SQUOTE,
- T_DQUOTE, T_COLON, T_AMP, T_IF, T_ELSE, T_ASSIGN, T_SEMI
} TokType;
typedef struct {