Some progress on the assembler
This commit is contained in:
@@ -23,14 +23,14 @@ posts = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
fun render_comment(c)
|
fun render_comment(c)
|
||||||
return <div class="comment">
|
<div class="comment">
|
||||||
<a>$c.author; ($c.date;)</a>
|
<a>$c.author; ($c.date;)</a>
|
||||||
<p>$c.content;</p>
|
<p>$c.content;</p>
|
||||||
<div class="comment-children">
|
<div class="comment-children">
|
||||||
$for child in c.children:
|
$for child in c.children:
|
||||||
render_comment(child);
|
render_comment(child);
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
|||||||
+132
-10
@@ -1,4 +1,7 @@
|
|||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
|
#include "assemble.h"
|
||||||
|
|
||||||
|
#define MAX_SCOPES 32
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SCOPE_FUNC,
|
SCOPE_FUNC,
|
||||||
@@ -9,19 +12,62 @@ typedef enum {
|
|||||||
} ScopeType;
|
} ScopeType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Node *funcs;
|
ScopeType type;
|
||||||
int num_funcs;
|
// TODO
|
||||||
int cap_funcs;
|
|
||||||
} Scope;
|
} 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)
|
void assemble_node(Node *node)
|
||||||
{
|
{
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
|
|
||||||
case NODE_FUNC_DECL:
|
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;
|
break;
|
||||||
|
|
||||||
case NODE_FUNC_CALL:
|
case NODE_FUNC_CALL:
|
||||||
@@ -29,6 +75,18 @@ void assemble_node(Node *node)
|
|||||||
Node *func = node->left;
|
Node *func = node->left;
|
||||||
Node *args = node->right;
|
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) {
|
if (func->type == NODE_VALUE_VAR) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
@@ -37,12 +95,36 @@ void assemble_node(Node *node)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_BLOCK:
|
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;
|
break;
|
||||||
|
|
||||||
case NODE_IFELSE:
|
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;
|
break;
|
||||||
|
|
||||||
case NODE_FOR:
|
case NODE_FOR:
|
||||||
|
{
|
||||||
|
assemble_node(node->for_set);
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_WHILE:
|
case NODE_WHILE:
|
||||||
@@ -52,68 +134,108 @@ void assemble_node(Node *node)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_POS:
|
case NODE_OPER_POS:
|
||||||
|
assemble_node(node->left);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_NEG:
|
case NODE_OPER_NEG:
|
||||||
|
assemble_node(node->left);
|
||||||
|
append(out, OPCODE_NEG);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_ASS:
|
case NODE_OPER_ASS:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_EQL:
|
case NODE_OPER_EQL:
|
||||||
|
assemble_node(node->left);
|
||||||
|
assemble_node(node->right);
|
||||||
|
append(out, OPCODE_EQL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_NQL:
|
case NODE_OPER_NQL:
|
||||||
|
assemble_node(node->left);
|
||||||
|
assemble_node(node->right);
|
||||||
|
append(out, OPCODE_NQL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_LSS:
|
case NODE_OPER_LSS:
|
||||||
|
assemble_node(node->left);
|
||||||
|
assemble_node(node->right);
|
||||||
|
append(out, OPCODE_LSS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_GRT:
|
case NODE_OPER_GRT:
|
||||||
|
assemble_node(node->left);
|
||||||
|
assemble_node(node->right);
|
||||||
|
append(out, OPCODE_GRT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_ADD:
|
case NODE_OPER_ADD:
|
||||||
|
assemble_node(node->left);
|
||||||
|
assemble_node(node->right);
|
||||||
|
append(out, OPCODE_ADD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_SUB:
|
case NODE_OPER_SUB:
|
||||||
|
assemble_node(node->left);
|
||||||
|
assemble_node(node->right);
|
||||||
|
append(out, OPCODE_SUB);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_MUL:
|
case NODE_OPER_MUL:
|
||||||
|
assemble_node(node->left);
|
||||||
|
assemble_node(node->right);
|
||||||
|
append(out, OPCODE_MUL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_DIV:
|
case NODE_OPER_DIV:
|
||||||
|
assemble_node(node->left);
|
||||||
|
assemble_node(node->right);
|
||||||
|
append(out, OPCODE_DIV);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_OPER_MOD:
|
case NODE_OPER_MOD:
|
||||||
|
assemble_node(node->left);
|
||||||
|
assemble_node(node->right);
|
||||||
|
append(out, OPCODE_MOD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_VALUE_INT:
|
case NODE_VALUE_INT:
|
||||||
|
append_u8 (out, OPCODE_PUSHI);
|
||||||
|
append_u64(out, node->ival);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_VALUE_FLOAT:
|
case NODE_VALUE_FLOAT:
|
||||||
|
append_u8 (out, OPCODE_PUSHF);
|
||||||
|
append_f64(out, node->fval);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_VALUE_STR:
|
case NODE_VALUE_STR:
|
||||||
|
append_u8 (out, OPCODE_PUSHS);
|
||||||
|
append_u64(out, xxx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_VALUE_VAR:
|
case NODE_VALUE_VAR:
|
||||||
|
append_u8 (out, OPCODE_PUSHV);
|
||||||
|
append_u64(out, node->ival);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_VALUE_HTML:
|
case NODE_VALUE_HTML:
|
||||||
|
TODO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_VALUE_ARRAY:
|
case NODE_VALUE_ARRAY:
|
||||||
|
append_u8 (out, OPCODE_PUSHA);
|
||||||
|
append_u64(out, xxx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_VALUE_MAP:
|
case NODE_VALUE_MAP:
|
||||||
break;
|
append_u8 (out, OPCODE_PUSHM);
|
||||||
|
append_u64(out, xxx);
|
||||||
case NODE_HTML_PARAM:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void assemble(Node *root)
|
AssembleResult assemble(Node *root)
|
||||||
{
|
{
|
||||||
|
assemble_node(root);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
Reference in New Issue
Block a user