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
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
$c.content;