static AST* ast(ASTType type) {
AST* tree = emalloc(sizeof(AST));
memset(tree, 0, sizeof(AST));
- tree->type = type;
+ tree->nodetype = type;
return tree;
}
}
char* string_value(AST* val) {
- assert(val->type == AST_STRING);
+ assert(val->nodetype == AST_STRING);
return val->value.text;
}
}
char* symbol_value(AST* val) {
- assert(val->type == AST_SYMBOL);
+ assert(val->nodetype == AST_SYMBOL);
return val->value.text;
}
}
uint32_t char_value(AST* val) {
- assert(val->type == AST_CHAR);
+ assert(val->nodetype == AST_CHAR);
return val->value.character;
}
}
intptr_t integer_value(AST* val) {
- assert(val->type == AST_INT);
+ assert(val->nodetype == AST_INT);
return val->value.integer;
}
}
double float_value(AST* val) {
- assert(val->type == AST_FLOAT);
+ assert(val->nodetype == AST_FLOAT);
return val->value.floating;
}
}
bool bool_value(AST* val) {
- assert(val->type == AST_BOOL);
+ assert(val->nodetype == AST_BOOL);
return val->value.boolean;
}
}
char* ident_value(AST* val) {
- assert(val->type == AST_IDENT);
+ assert(val->nodetype == AST_IDENT);
return val->value.text;
}
-AST* Let(Tok* name, AST* value) {
- AST* node = ast(AST_LET);
- node->value.let.name = name->value.text;
- node->value.let.value = value;
+AST* Var(Tok* name, AST* value, bool constant) {
+ AST* node = ast(AST_VAR);
+ node->value.var.name = name->value.text;
+ node->value.var.value = value;
+ node->value.var.constant = constant;
return node;
}
-char* let_name(AST* let) {
- assert(let->type == AST_LET);
- return let->value.let.name;
+char* var_name(AST* var) {
+ assert(var->nodetype == AST_VAR);
+ return var->value.var.name;
}
-AST* let_value(AST* let) {
- assert(let->type == AST_LET);
- return let->value.let.value;
+AST* var_value(AST* var) {
+ assert(var->nodetype == AST_VAR);
+ return var->value.var.value;
+}
+
+bool var_const(AST* var) {
+ assert(var->nodetype == AST_VAR);
+ return var->value.var.constant;
}
%%
-<<EOF>> { return T_END_FILE; }
+[ \t\r\n] { /* whitespace is insignificant */ }
+<<EOF>> { return T_END_FILE; }
"let" { return T_LET; }
+"var" { return T_VAR; }
+
"if" { return T_IF; }
"then" { return T_THEN; }
"else" { return T_ELSE; }
#include <sclpl.h>
-static AST* const_definition(Parser* p);
+static AST* const_definition(Parser* p, bool constant);
static AST* const_expression(Parser* p);
static AST* definition(Parser* p);
static AST* expression(Parser* p);
AST* toplevel(Parser* p) {
AST* ret = NULL;
if (!match(p, T_END_FILE)) {
- if (accept(p, T_LET))
- ret = const_definition(p);
+ TokType type = peek(p)->type;
+ if (accept(p, T_LET) || accept(p, T_VAR))
+ ret = const_definition(p, (type == T_LET));
else
error(p, "only definitions are allowed at the toplevel");
}
return ret;
}
-static AST* const_definition(Parser* p) {
+static AST* const_definition(Parser* p, bool constant) {
AST* expr;
Tok* id = expect_val(p, T_ID);
-// if (peek(p)->type == T_LPAR) {
-// expr = function(p);
-// } else {
- type_annotation(p);
- expect(p, T_ASSIGN);
- expr = const_expression(p);
- expect(p, T_END);
-// }
- return Let(id, expr);
+ type_annotation(p);
+ expect(p, T_ASSIGN);
+ expr = const_expression(p);
+ return Var(id, expr, constant);
}
static AST* const_expression(Parser* p) {
static void pprint_literal(FILE* file, AST* tree, int depth)
{
- printf("%s:", tree_type_to_string(tree->type));
- switch(tree->type) {
+ printf("%s:", tree_type_to_string(tree->nodetype));
+ switch(tree->nodetype) {
case AST_STRING: printf("\"%s\"", string_value(tree)); break;
case AST_SYMBOL: printf("%s", symbol_value(tree)); break;
case AST_IDENT: printf("%s", ident_value(tree)); break;
return;
}
print_indent(file, depth);
- switch (tree->type) {
- case AST_LET:
- printf("(let %s ", let_name(tree));
- pprint_tree(file, let_value(tree), depth);
- printf(")");
+ switch (tree->nodetype) {
+ case AST_VAR:
+ printf("(%s %s ",
+ (var_const(tree) ? "let" : "var"),
+ var_name(tree));
+ pprint_tree(file, var_value(tree), depth);
+ printf(")\n");
break;
default:
/* Token Types
*****************************************************************************/
typedef enum {
- T_NONE, T_ERROR, T_END_FILE, T_ID, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING,
+ T_NONE, T_ERROR, T_END_FILE, T_LET, T_VAR,
+ 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_END, T_COLON, T_AMP, T_LET, T_IF, T_THEN, T_ELSE, T_ASSIGN
+ T_DQUOTE, T_END, T_COLON, T_AMP, T_IF, T_THEN, T_ELSE, T_ASSIGN
} TokType;
typedef struct {
/* AST Types
*****************************************************************************/
typedef enum {
- AST_LET, AST_STRING, AST_SYMBOL, AST_CHAR, AST_INT, AST_FLOAT, AST_BOOL, AST_IDENT
+ AST_VAR, AST_STRING, AST_SYMBOL, AST_CHAR, AST_INT, AST_FLOAT, AST_BOOL, AST_IDENT
} ASTType;
typedef struct AST {
- ASTType type;
+ ASTType nodetype;
+ Type* datatype;
union {
/* Definition Node */
struct {
char* name;
- struct AST* type;
struct AST* value;
- } let;
+ bool constant;
+ } var;
/* String, Symbol, Identifier */
char* text;
/* Character */
char* ident_value(AST* val);
/* Definition */
-AST* Let(Tok* name, AST* value);
-char* let_name(AST* let);
-AST* let_value(AST* let);
+AST* Var(Tok* name, AST* value, bool constant);
+char* var_name(AST* var);
+AST* var_value(AST* var);
+bool var_const(AST* var);
/* Pretty Printing
*****************************************************************************/