summaryrefslogtreecommitdiff
path: root/src/sys/np
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-10-02 19:05:33 -0400
committerIan Moffett <ian@osmora.org>2025-10-02 19:05:33 -0400
commit07b352ff545427881c32d6dd8b03539025bbca80 (patch)
tree41c89e03e1926502f0c1abe3b55d5e3eb1587b59 /src/sys/np
parent187e961cfcf6885b8f620b37c7f7266b3ba063d5 (diff)
np: codegen: Implement initial stack based codegen
This commit introduces the groundwork for the AMD64 PIIR backend. We will not follow through with the plans of using abstract syntax trees as they'll overly complicate the project. Instead we'll utilize a ring buffer to store the list of instructions and a stack machine for the IR code. Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'src/sys/np')
-rw-r--r--src/sys/np/codegen/gen_piir.c18
-rw-r--r--src/sys/np/core/np_parse.c31
2 files changed, 29 insertions, 20 deletions
diff --git a/src/sys/np/codegen/gen_piir.c b/src/sys/np/codegen/gen_piir.c
index e139465..e6623ac 100644
--- a/src/sys/np/codegen/gen_piir.c
+++ b/src/sys/np/codegen/gen_piir.c
@@ -66,12 +66,12 @@ piir_push(struct piir_stack *stack, ir_byte_t byte)
return -EINVAL;
}
- if (stack->op_i >= PIIR_STACK_SIZE - 1) {
+ if (stack->op_head >= PIIR_STACK_SIZE - 1) {
return -1;
}
spinlock_acquire(&stack->lock);
- stack->opstore[stack->op_i++] = byte;
+ stack->opstore[stack->op_head++] = byte;
spinlock_release(&stack->lock);
return 0;
}
@@ -88,12 +88,22 @@ piir_pop(struct piir_stack *stack)
return -EINVAL;
}
- if (stack->op_i == 0) {
+ /* Don't read past what we can */
+ if (stack->op_tail == stack->op_head) {
+ stack->op_tail = 0;
+ stack->op_head = 0;
return -1;
}
spinlock_acquire(&stack->lock);
- byte = stack->opstore[--stack->op_i];
+
+ /* Grab a byte, reset pointers if empty */
+ byte = stack->opstore[stack->op_tail++];
+ if (stack->op_tail == stack->op_head) {
+ stack->op_tail = 0;
+ stack->op_head = 0;
+ }
+
spinlock_release(&stack->lock);
return byte;
}
diff --git a/src/sys/np/core/np_parse.c b/src/sys/np/core/np_parse.c
index fd35e3c..3eefde5 100644
--- a/src/sys/np/core/np_parse.c
+++ b/src/sys/np/core/np_parse.c
@@ -269,16 +269,16 @@ parse_proc(struct np_work *work, struct ast_node **npp, struct lex_token *tok)
* Parse a token
*
* @work: Input work
- * @root: Root AST node
* @tok: Current token
*/
static int
-parse_token(struct np_work *work, struct ast_node *root, struct lex_token *tok)
+parse_token(struct np_work *work, struct lex_token *tok)
{
tt_t tt;
int error;
struct ast_node *np;
+#define PIIR_PUSH(BYTE) piir_push(work->piir_stack, (BYTE))
/*
* XXX: wrapped in "[]" indicates optional
*
@@ -296,9 +296,15 @@ parse_token(struct np_work *work, struct ast_node *root, struct lex_token *tok)
++work->begin_depth;
case TT_END:
- /* Do the begin statements match? */
+ /*
+ * Check if the 'begin' statements match, if they do
+ * we'll decrease the depth and push a NIL return
+ *
+ * TODO: We'll need to handle returns better
+ */
if (work->begin_depth > 0) {
--work->begin_depth;
+ PIIR_PUSH(PIIR_RET_NIL);
break;
}
@@ -321,18 +327,17 @@ parse_token(struct np_work *work, struct ast_node *root, struct lex_token *tok)
return -1;
}
- root->left = NULL; /* arguments */
- root->right = np;
+ /* XXX: NOP for testing */
+ PIIR_PUSH(PIIR_NOP);
break;
}
-
+#undef PIIR_PUSH
return 0;
}
int
parse_work(struct np_work *work)
{
- struct ast_node *root;
struct lex_token tok;
int error = 0;
@@ -341,14 +346,6 @@ parse_work(struct np_work *work)
return -EINVAL;
}
- /* Get the AST root node */
- work->ast_root = ast_alloc(work);
- root = work->ast_root;
- if (work->ast_root == NULL) {
- pr_error("failed to alloc root AST\n");
- return -ENOMEM;
- }
-
/* Initialize PIIR */
error = piir_stack_new(work, &work->piir_stack);
if (error < 0) {
@@ -371,11 +368,13 @@ parse_work(struct np_work *work)
return -1;
}
- if (parse_token(work, root, &tok) < 0) {
+ if (parse_token(work, &tok) < 0) {
return -1;
}
}
+ piir_inject(work);
+
/*
* If there are more begin clauses than end
* clauses, someone mismatched them.