diff --git a/main.wl b/main.wl index ef0811c..1f5e905 100644 --- a/main.wl +++ b/main.wl @@ -23,14 +23,14 @@ posts = [ ]; fun render_comment(c) - return
+
$c.author; ($c.date;)

$c.content;

$for child in c.children: render_comment(child);
-
; +
diff --git a/src/assemble.c b/src/assemble.c index b542d17..bfa0d74 100644 --- a/src/assemble.c +++ b/src/assemble.c @@ -1,4 +1,7 @@ #include "parse.h" +#include "assemble.h" + +#define MAX_SCOPES 32 typedef enum { SCOPE_FUNC, @@ -9,19 +12,62 @@ typedef enum { } ScopeType; typedef struct { - Node *funcs; - int num_funcs; - int cap_funcs; + ScopeType type; + // TODO } Scope; +typedef struct { + int depth; + Scope scopes[MAX_SCOPES]; +} Assembler; + +int count_nodes(Node *head) +{ + int n = 0; + Node *node = head; + while (node) { + n++; + node = node->next; + } + return n; +} + void assemble_node(Node *node) { switch (node->type) { case NODE_FUNC_DECL: - break; + { + append_u8 (out, OPCODE_JUMP); + append_u64(out, xxx); - case NODE_FUNC_ARG: + int arg_count = count_nodes(node->func_args); + + Node *preallocated[32]; + Node *args = preallocated; + if (arg_count > COUNT(preallocated)) { + args = malloc(arg_count * sizeof(Node*)); + if (args == NULL) { + // TODO + } + } + + for (int i = arg_count-1; i >= 0; i--) { + append_u8 (out, OPCODE_ASS); + append_u64(out, xxx); + } + + if (is_expr(node->func_body)) { + assemble_node(node->func_body); + append_u8(out, OPCODE_RET); + } else + assemble_node(node->func_body); + + append_u8(out, OPCODE_NOPE); + + if (args != preallocated) + free(args); + } break; case NODE_FUNC_CALL: @@ -29,6 +75,18 @@ void assemble_node(Node *node) Node *func = node->left; Node *args = node->right; + int arg_count = 0; + Node *arg = args; + while (arg) { + assemble_node(arg); + arg_count++; + arg = arg->next; + } + + assemble_node(arg); + append_u8(OPCODE_CALL); + append_u32(arg_count); + if (func->type == NODE_VALUE_VAR) { // TODO } @@ -37,12 +95,36 @@ void assemble_node(Node *node) break; case NODE_BLOCK: + { + Node *stmt = node->child; + while (stmt) { + assemble_node(stmt); + if (is_expr(stmt)) + append_u8(out, OPCODE_POP); + stmt = stmt->next; + } + } break; case NODE_IFELSE: + { + assemble_node(node->cond); + + append_u8 (out, OPCODE_JIFP); + append_u32(out, xxx); + + assemble_node(node->left); + + if (node->right) + assemble_node(node->right); + } break; case NODE_FOR: + { + assemble_node(node->for_set); + // TODO + } break; case NODE_WHILE: @@ -52,68 +134,108 @@ void assemble_node(Node *node) break; case NODE_OPER_POS: + assemble_node(node->left); break; case NODE_OPER_NEG: + assemble_node(node->left); + append(out, OPCODE_NEG); break; case NODE_OPER_ASS: break; case NODE_OPER_EQL: + assemble_node(node->left); + assemble_node(node->right); + append(out, OPCODE_EQL); break; case NODE_OPER_NQL: + assemble_node(node->left); + assemble_node(node->right); + append(out, OPCODE_NQL); break; case NODE_OPER_LSS: + assemble_node(node->left); + assemble_node(node->right); + append(out, OPCODE_LSS); break; case NODE_OPER_GRT: + assemble_node(node->left); + assemble_node(node->right); + append(out, OPCODE_GRT); break; case NODE_OPER_ADD: + assemble_node(node->left); + assemble_node(node->right); + append(out, OPCODE_ADD); break; case NODE_OPER_SUB: + assemble_node(node->left); + assemble_node(node->right); + append(out, OPCODE_SUB); break; case NODE_OPER_MUL: + assemble_node(node->left); + assemble_node(node->right); + append(out, OPCODE_MUL); break; case NODE_OPER_DIV: + assemble_node(node->left); + assemble_node(node->right); + append(out, OPCODE_DIV); break; case NODE_OPER_MOD: + assemble_node(node->left); + assemble_node(node->right); + append(out, OPCODE_MOD); break; case NODE_VALUE_INT: + append_u8 (out, OPCODE_PUSHI); + append_u64(out, node->ival); break; case NODE_VALUE_FLOAT: + append_u8 (out, OPCODE_PUSHF); + append_f64(out, node->fval); break; case NODE_VALUE_STR: + append_u8 (out, OPCODE_PUSHS); + append_u64(out, xxx); break; case NODE_VALUE_VAR: + append_u8 (out, OPCODE_PUSHV); + append_u64(out, node->ival); break; case NODE_VALUE_HTML: + TODO; break; case NODE_VALUE_ARRAY: + append_u8 (out, OPCODE_PUSHA); + append_u64(out, xxx); break; case NODE_VALUE_MAP: - break; - - case NODE_HTML_PARAM: + append_u8 (out, OPCODE_PUSHM); + append_u64(out, xxx); break; } } -void assemble(Node *root) +AssembleResult assemble(Node *root) { - + assemble_node(root); } diff --git a/src/assemble.h b/src/assemble.h new file mode 100644 index 0000000..f5dbd12 --- /dev/null +++ b/src/assemble.h @@ -0,0 +1,36 @@ + +enum { + OPCODE_NOPE = 0x00, + OPCODE_PUSHI = 0x01, + OPCODE_PUSHF = 0x02, + OPCODE_PUSHS = 0x03, + OPCODE_PUSHV = 0x04, + OPCODE_PUSHA = 0x05, + OPCODE_PUSHM = 0x06, + OPCODE_POP = 0x07, + OPCODE_NEG = 0x08, + OPCODE_EQL = 0x09, + OPCODE_NQL = 0x0A, + OPCODE_LSS = 0x0B, + OPCODE_GRT = 0x0C, + OPCODE_ADD = 0x0D, + OPCODE_SUB = 0x0E, + OPCODE_MUL = 0x0F, + OPCODE_DIV = 0x10, + OPCODE_MOD = 0x20, + OPCODE_JUMP = 0x30, + OPCODE_JIFP = 0x40, + OPCODE_CALL = 0x41, + OPCODE_RET = 0x42, +}; + +typedef struct { + void *ptr; + int len; +} Program; + +typedef struct { + Program program; +} AssembleResult; + +AssembleResult assemble(Node *root); \ No newline at end of file