Some progress on the assembler
This commit is contained in:
@@ -23,14 +23,14 @@ posts = [
|
||||
];
|
||||
|
||||
fun render_comment(c)
|
||||
return <div class="comment">
|
||||
<div class="comment">
|
||||
<a>$c.author; ($c.date;)</a>
|
||||
<p>$c.content;</p>
|
||||
<div class="comment-children">
|
||||
$for child in c.children:
|
||||
render_comment(child);
|
||||
</div>
|
||||
</div>;
|
||||
</div>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
|
||||
+132
-10
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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