|
@@ -23,7 +23,7 @@
|
|
|
#include "erupt.h"
|
|
|
#include "ast.h"
|
|
|
|
|
|
-ast_node_t *create_var(char *name, ast_type_t data_type, char *value, bool mutable)
|
|
|
+ast_node_t *create_var(char *name, ast_type_t data_type, bool mutable)
|
|
|
{
|
|
|
ast_node_t *node = smalloc(sizeof(ast_node_t));
|
|
|
|
|
@@ -32,56 +32,10 @@ ast_node_t *create_var(char *name, ast_type_t data_type, char *value, bool mutab
|
|
|
node->var.data_type = data_type;
|
|
|
node->var.mutable = mutable;
|
|
|
|
|
|
- switch (data_type) {
|
|
|
- case I8:
|
|
|
- node->var.int8_value = strtol(value, NULL, 10);
|
|
|
- break;
|
|
|
- case I16:
|
|
|
- node->var.int16_value = strtol(value, NULL, 10);
|
|
|
- break;
|
|
|
- case I32:
|
|
|
- node->var.int32_value = strtol(value, NULL, 10);
|
|
|
- break;
|
|
|
- case I64:
|
|
|
- node->var.int64_value = strtoll(value, NULL, 10);
|
|
|
- break;
|
|
|
- case U8:
|
|
|
- node->var.uint8_value = strtoul(value, NULL, 10);
|
|
|
- break;
|
|
|
- case U16:
|
|
|
- node->var.uint16_value = strtoul(value, NULL, 10);
|
|
|
- break;
|
|
|
- case U32:
|
|
|
- node->var.uint32_value = strtoul(value, NULL, 10);
|
|
|
- break;
|
|
|
- case U64:
|
|
|
- node->var.uint64_value = strtoull(value, NULL, 10);
|
|
|
- break;
|
|
|
- case STR:
|
|
|
- node->var.str_value = strdup(value);
|
|
|
- break;
|
|
|
- case BOOL: {
|
|
|
- bool state = NULL;
|
|
|
-
|
|
|
- if (strcmp(value, TRUE_KEYWORD) == 0)
|
|
|
- state = true;
|
|
|
- else if (strcmp(value, FALSE_KEYWORD) == 0)
|
|
|
- state = false;
|
|
|
-
|
|
|
- node->var.bool_value = state;
|
|
|
- break;
|
|
|
- }
|
|
|
- case FLOAT:
|
|
|
- node->var.float_value = strtof(value, NULL);
|
|
|
- break;
|
|
|
- default:
|
|
|
- erupt_fatal_error("somehow got invalid data type\n");
|
|
|
- }
|
|
|
-
|
|
|
return node;
|
|
|
}
|
|
|
|
|
|
-ast_node_t *create_fn_proto(char *name, ast_var_t **args, size_t arg_count, ast_type_t data_type)
|
|
|
+ast_node_t *create_fn_proto(char *name, ast_node_list_t *args, ast_type_t data_type)
|
|
|
{
|
|
|
ast_node_t *node = smalloc(sizeof(ast_node_t));
|
|
|
|
|
@@ -89,17 +43,12 @@ ast_node_t *create_fn_proto(char *name, ast_var_t **args, size_t arg_count, ast_
|
|
|
node->prototype.name = strdup(name);
|
|
|
node->prototype.data_type = data_type;
|
|
|
|
|
|
- node->prototype.args = smalloc(sizeof(ast_var_t) * arg_count);
|
|
|
-
|
|
|
- for (size_t i = 0; i < arg_count; ++i)
|
|
|
- node->prototype.args[i] = args[i];
|
|
|
-
|
|
|
- node->prototype.arg_count = arg_count;
|
|
|
+ node->prototype.args = args;
|
|
|
|
|
|
return node;
|
|
|
}
|
|
|
|
|
|
-ast_node_t *create_fn(ast_node_t *prototype, ast_node_t *body)
|
|
|
+ast_node_t *create_fn(ast_node_t *prototype, ast_node_list_t *body)
|
|
|
{
|
|
|
ast_node_t *node = smalloc(sizeof(ast_node_t));
|
|
|
|
|
@@ -110,110 +59,129 @@ ast_node_t *create_fn(ast_node_t *prototype, ast_node_t *body)
|
|
|
return node;
|
|
|
}
|
|
|
|
|
|
-ast_node_t *create_call(char *name, ast_node_t **args, size_t arg_count)
|
|
|
+ast_node_t *create_call(char *name, ast_node_list_t *args)
|
|
|
{
|
|
|
ast_node_t *node = smalloc(sizeof(ast_node_t));
|
|
|
|
|
|
node->type = TYPE_CALL;
|
|
|
node->call.name = strdup(name);
|
|
|
|
|
|
- node->call.args = smalloc(sizeof(char) * arg_count);
|
|
|
-
|
|
|
- for (size_t i = 0; i < arg_count; ++i)
|
|
|
- node->call.args[i] = args[i];
|
|
|
-
|
|
|
- node->call.arg_count = arg_count;
|
|
|
+ node->call.args = args;
|
|
|
|
|
|
return node;
|
|
|
}
|
|
|
|
|
|
-ast_node_t *create_if(ast_node_t *condition, ast_node_t *true_body,
|
|
|
- ast_node_t *false_body)
|
|
|
+ast_node_t *create_if(ast_node_t *condition, ast_node_list_t *true_body,
|
|
|
+ ast_node_list_t *false_body)
|
|
|
{
|
|
|
ast_node_t *node = smalloc(sizeof(ast_node_t));
|
|
|
|
|
|
node->type = TYPE_IF;
|
|
|
- node->if_exp.condition = condition;
|
|
|
- node->if_exp.true_body = true_body;
|
|
|
- node->if_exp.false_body = false_body;
|
|
|
+ node->if_expr.condition = condition;
|
|
|
+ node->if_expr.true_body = true_body;
|
|
|
+ node->if_expr.false_body = false_body;
|
|
|
|
|
|
return node;
|
|
|
}
|
|
|
|
|
|
-ast_node_t *create_bin_exp(ast_op_t operator, ast_node_t *lhs, ast_node_t *rhs)
|
|
|
+ast_node_t *create_bin_expr(ast_op_t operator, ast_node_t *lhs, ast_node_t *rhs)
|
|
|
{
|
|
|
ast_node_t *node = smalloc(sizeof(ast_node_t));
|
|
|
|
|
|
- node->type = TYPE_BIN_EXP;
|
|
|
- node->bin_exp.operator = operator;
|
|
|
- node->bin_exp.lhs = lhs;
|
|
|
- node->bin_exp.rhs = rhs;
|
|
|
+ node->type = TYPE_BIN_EXPR;
|
|
|
+ node->bin_expr.operator = operator;
|
|
|
+ node->bin_expr.lhs = lhs;
|
|
|
+ node->bin_expr.rhs = rhs;
|
|
|
|
|
|
return node;
|
|
|
}
|
|
|
|
|
|
+ast_node_list_t *create_node_list(void)
|
|
|
+{
|
|
|
+ ast_node_list_t *nl = smalloc(sizeof(ast_node_list_t));
|
|
|
+
|
|
|
+ nl->node = NULL;
|
|
|
+ nl->next = NULL;
|
|
|
+
|
|
|
+ return nl;
|
|
|
+}
|
|
|
+
|
|
|
+void swap_lists(ast_node_list_t *a, ast_node_list_t *b)
|
|
|
+{
|
|
|
+ ast_node_list_t *tmp = a;
|
|
|
+ a = b;
|
|
|
+ b = tmp;
|
|
|
+}
|
|
|
+
|
|
|
+static void destroy_node(ast_node_t *node)
|
|
|
+{
|
|
|
+ if (!node)
|
|
|
+ return;
|
|
|
+
|
|
|
+ switch(node->type) {
|
|
|
+ case TYPE_VAR:
|
|
|
+ if (node->var.name)
|
|
|
+ free(node->var.name);
|
|
|
+ break;
|
|
|
+ case TYPE_PROTO:
|
|
|
+ if (node->prototype.name)
|
|
|
+ free(node->prototype.name);
|
|
|
+
|
|
|
+ if (node->prototype.args)
|
|
|
+ destroy_ast(node->prototype.args);
|
|
|
+ break;
|
|
|
+ case TYPE_FN:
|
|
|
+ if (node->fn.prototype)
|
|
|
+ destroy_node(node->fn.prototype);
|
|
|
+
|
|
|
+ if (node->fn.body)
|
|
|
+ destroy_ast(node->fn.body);
|
|
|
+ break;
|
|
|
+ case TYPE_CALL:
|
|
|
+ if (node->call.name)
|
|
|
+ free(node->call.name);
|
|
|
+
|
|
|
+ if (node->call.args)
|
|
|
+ destroy_ast(node->call.args);
|
|
|
+ break;
|
|
|
+ case TYPE_IF:
|
|
|
+ if (node->if_expr.condition)
|
|
|
+ destroy_node(node->if_expr.condition);
|
|
|
+
|
|
|
+ if (node->if_expr.true_body)
|
|
|
+ destroy_ast(node->if_expr.true_body);
|
|
|
+
|
|
|
+ if (node->if_expr.false_body)
|
|
|
+ destroy_ast(node->if_expr.false_body);
|
|
|
+ break;
|
|
|
+ case TYPE_BIN_EXPR:
|
|
|
+ if (node->bin_expr.lhs)
|
|
|
+ destroy_node(node->bin_expr.lhs);
|
|
|
+ if (node->bin_expr.rhs)
|
|
|
+ destroy_node(node->bin_expr.rhs);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ free(node);
|
|
|
+}
|
|
|
+
|
|
|
void destroy_ast(ast_node_list_t *nl)
|
|
|
{
|
|
|
- do {
|
|
|
- switch(nl->node->type) {
|
|
|
- case TYPE_VAR:
|
|
|
- if (nl->node->var.name)
|
|
|
- free(nl->node->var.name);
|
|
|
- break;
|
|
|
- case TYPE_PROTO:
|
|
|
- if (nl->node->prototype.name)
|
|
|
- free(nl->node->prototype.name);
|
|
|
-
|
|
|
- for (size_t i = 0; i < nl->node->prototype.arg_count; ++i)
|
|
|
- free(nl->node->prototype.args[i]);
|
|
|
-
|
|
|
- free(nl->node->prototype.args);
|
|
|
- break;
|
|
|
- case TYPE_FN:
|
|
|
- if (nl->node->fn.prototype)
|
|
|
- free(nl->node->fn.prototype);
|
|
|
-
|
|
|
- if (nl->node->fn.body)
|
|
|
- free(nl->node->fn.body);
|
|
|
- break;
|
|
|
- case TYPE_CALL:
|
|
|
- if (nl->node->call.name)
|
|
|
- free(nl->node->call.name);
|
|
|
-
|
|
|
- for (size_t i = 0; i < nl->node->call.arg_count; ++i)
|
|
|
- free(nl->node->call.args[i]);
|
|
|
-
|
|
|
- free(nl->node->call.args);
|
|
|
- break;
|
|
|
- case TYPE_IF:
|
|
|
- if (nl->node->if_exp.condition)
|
|
|
- free(nl->node->if_exp.condition);
|
|
|
-
|
|
|
- if (nl->node->if_exp.true_body)
|
|
|
- free(nl->node->if_exp.true_body);
|
|
|
-
|
|
|
- if (nl->node->if_exp.false_body)
|
|
|
- free(nl->node->if_exp.false_body);
|
|
|
- break;
|
|
|
- case TYPE_BIN_EXP:
|
|
|
- if (nl->node->bin_exp.lhs)
|
|
|
- free(nl->node->bin_exp.lhs);
|
|
|
- if (nl->node->bin_exp.rhs)
|
|
|
- free(nl->node->bin_exp.rhs);
|
|
|
- break;
|
|
|
- }
|
|
|
+ if (!nl)
|
|
|
+ return;
|
|
|
|
|
|
- free(nl->node);
|
|
|
- nl = nl->next;
|
|
|
- } while (nl->next != NULL);
|
|
|
+ do {
|
|
|
+ destroy_node(nl->node);
|
|
|
+ } while ((nl = nl->next));
|
|
|
|
|
|
free(nl);
|
|
|
- verbose_printf("destroyed ast\n");
|
|
|
}
|
|
|
|
|
|
-
|
|
|
static void dump_node(ast_node_t *node)
|
|
|
{
|
|
|
+ if (!node)
|
|
|
+ return;
|
|
|
+
|
|
|
switch (node->type) {
|
|
|
case TYPE_VAR:
|
|
|
printf("variable:\n\tname: %s\n\ttype: %u\n\tmutable:%d\n",
|
|
@@ -225,7 +193,14 @@ static void dump_node(ast_node_t *node)
|
|
|
break;
|
|
|
case TYPE_FN:
|
|
|
printf("function:\n");
|
|
|
- dump_node(node->fn.prototype);
|
|
|
+
|
|
|
+ if (node->fn.prototype)
|
|
|
+ dump_node(node->fn.prototype);
|
|
|
+
|
|
|
+ if (node->fn.body) {
|
|
|
+ printf("body:\n");
|
|
|
+ dump_node_list(node->fn.body);
|
|
|
+ }
|
|
|
break;
|
|
|
case TYPE_CALL:
|
|
|
/* TODO */
|
|
@@ -233,16 +208,15 @@ static void dump_node(ast_node_t *node)
|
|
|
case TYPE_IF:
|
|
|
/* TODO */
|
|
|
break;
|
|
|
- case TYPE_BIN_EXP:
|
|
|
+ case TYPE_BIN_EXPR:
|
|
|
/* TODO */
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void dump_nodes(ast_node_list_t *nl)
|
|
|
+void dump_node_list(ast_node_list_t *nl)
|
|
|
{
|
|
|
do {
|
|
|
dump_node(nl->node);
|
|
|
- nl = nl->next;
|
|
|
- } while (nl->next != NULL);
|
|
|
+ } while ((nl = nl->next));
|
|
|
}
|