merge emitters, add uxn emitter, update c emitter, update simple to use raw ascii for example

This commit is contained in:
zongor 2026-04-08 22:29:47 -07:00
parent b4512f2434
commit 8e430a9d46
10 changed files with 600 additions and 432 deletions

View File

@ -40,14 +40,37 @@ static char* readFile(const char* path) {
return buffer; return buffer;
} }
void print_help() {
printf("Usage: undar [options] file...\nOptions:\n\t-emit={c|u}\tEmitter output, currently C source and Uxn binary.\n\n");
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
if(argc != 2) return EXIT_FAILURE; if (argc > 1 && (seq(argv[1], "--help") || seq(argv[1], "-h"))) {
print_help();
return EXIT_SUCCESS;
}
char* source = readFile(argv[1]); if(argc != 3) {
compile(source); print_help();
return EXIT_FAILURE;
}
Emitter e;
if (seq(argv[1], "-emit=c")) {
e = c_emitter();
} else if (seq(argv[1], "-emit=u")) {
e = uxn_emitter();
} else {
printf("unknown emitter type\n");
return EXIT_FAILURE;
}
char* source = readFile(argv[2]);
compile(e, source);
free(source); free(source);
printf("\n");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

10
build
View File

@ -10,10 +10,6 @@ if [ -z $MODE ]; then
MODE='debug' MODE='debug'
fi fi
if [ -z $EMIT ]; then
EMIT='c'
fi
case $ARCH in case $ARCH in
"linux") "linux")
if [ -z $CC ]; then if [ -z $CC ]; then
@ -27,7 +23,7 @@ esac
# setup dirs # setup dirs
SRC_DIR=./arch/$ARCH SRC_DIR=./arch/$ARCH
BUILD_DIR=./out/$EMIT/$ARCH BUILD_DIR=./out/$ARCH
GEN_DIR=$BUILD_DIR/gen GEN_DIR=$BUILD_DIR/gen
TOOL_SRC=tools/file2header.c TOOL_SRC=tools/file2header.c
TOOL_EXE=$BUILD_DIR/file2header TOOL_EXE=$BUILD_DIR/file2header
@ -85,10 +81,10 @@ ${CC} -c parser.c -o $BUILD_DIR/parser.o $VM_BUILD_FLAGS
# Set up the final build command # Set up the final build command
case $ARCH in case $ARCH in
"linux") "linux")
BUILD_CMD="$CC -o $BUILD_DIR/undar $SRC_DIR/main.c emit/$EMIT/emit.c $LINK_FLAGS $BUILD_DIR/libc.o $BUILD_DIR/list.o $BUILD_DIR/lexer.o $BUILD_DIR/parser.o $BUILD_FLAGS $LINK_FLAGS" BUILD_CMD="$CC -o $BUILD_DIR/undar $SRC_DIR/main.c emit/c/emit.c emit/uxn/emit.c $LINK_FLAGS $BUILD_DIR/libc.o $BUILD_DIR/list.o $BUILD_DIR/lexer.o $BUILD_DIR/parser.o $BUILD_FLAGS $LINK_FLAGS"
;; ;;
"web") "web")
BUILD_CMD="$CC $SRC_DIR/main.c emit/$EMIT/emit.c $BUILD_DIR/libc.o $BUILD_DIR/list.o $BUILD_DIR/lexer.o $BUILD_DIR/parser.o -o $BUILD_DIR/undar.html $BUILD_FLAGS $LINK_FLAGS" BUILD_CMD="$CC $SRC_DIR/main.c emit/c/emit.c emit/uxn/emit.c $BUILD_DIR/libc.o $BUILD_DIR/list.o $BUILD_DIR/lexer.o $BUILD_DIR/parser.o -o $BUILD_DIR/undar.html $BUILD_FLAGS $LINK_FLAGS"
;; ;;
esac esac

118
emit.h
View File

@ -3,74 +3,72 @@
#include "libc.h" #include "libc.h"
typedef enum expression_config_e { typedef enum notation_type_e {
PREFIX, PREFIX,
INFIX, INFIX,
POSTFIX POSTFIX
} ExpressionConfig; } NotationType;
typedef enum output_config_e { typedef enum output_type_e {
BINARY, BINARY,
TEXT TEXT
} OutputConfig; } OutputType;
ExpressionConfig expression_config(); typedef void (*VoidArgEmit)();
OutputConfig output_config(); typedef void (*StrArgEmit)(const char *str, i32 length);
/** typedef struct emitter_s Emitter;
* Prolog is for all of the "setup" boilerplate struct emitter_s {
*/ NotationType notation;
void prolog(); OutputType output;
VoidArgEmit prolog;
VoidArgEmit epilogue;
VoidArgEmit emit_add;
VoidArgEmit emit_sub;
VoidArgEmit emit_mul;
VoidArgEmit emit_div;
VoidArgEmit emit_lt;
VoidArgEmit emit_le;
VoidArgEmit emit_gt;
VoidArgEmit emit_ge;
VoidArgEmit emit_ne;
VoidArgEmit emit_eq;
VoidArgEmit emit_false;
VoidArgEmit emit_true;
VoidArgEmit emit_nil;
VoidArgEmit emit_void;
StrArgEmit emit_int;
StrArgEmit emit_nat;
StrArgEmit emit_real;
StrArgEmit emit_byte;
StrArgEmit emit_str;
VoidArgEmit emit_bool_type;
VoidArgEmit emit_byte_type;
VoidArgEmit emit_int_type;
VoidArgEmit emit_nat_type;
VoidArgEmit emit_real_type;
VoidArgEmit emit_str_type;
VoidArgEmit emit_u8_type;
VoidArgEmit emit_i8_type;
VoidArgEmit emit_i16_type;
VoidArgEmit emit_u16_type;
VoidArgEmit emit_i32_type;
VoidArgEmit emit_u32_type;
VoidArgEmit emit_f32_type;
VoidArgEmit emit_array;
VoidArgEmit emit_function;
VoidArgEmit emit_plex;
VoidArgEmit emit_method;
VoidArgEmit emit_trait;
VoidArgEmit emit_const;
VoidArgEmit emit_print;
VoidArgEmit emit_neg;
VoidArgEmit emit_not;
VoidArgEmit emit_open_paren;
VoidArgEmit emit_close_paren;
};
/** Emitter c_emitter();
* Prolog is for all of the "cleanup" boilerplate Emitter uxn_emitter();
*/
void epilogue();
/**
* Emitters
*/
void emit_add();
void emit_sub();
void emit_mul();
void emit_div();
void emit_lt();
void emit_le();
void emit_gt();
void emit_ge();
void emit_ne();
void emit_eq();
void emit_false();
void emit_true();
void emit_nil();
void emit_void();
void emit_int(const char *str, i32 length);
void emit_nat(const char *str, i32 length);
void emit_real(const char *str, i32 length);
void emit_str(const char *str, i32 length);
void emit_bool_type();
void emit_byte_type();
void emit_int_type();
void emit_nat_type();
void emit_real_type();
void emit_str_type();
void emit_u8_type();
void emit_i8_type();
void emit_i16_type();
void emit_u16_type();
void emit_i32_type();
void emit_u32_type();
void emit_f32_type();
void emit_array();
void emit_function();
void emit_plex();
void emit_method();
void emit_trait();
void emit_const();
void emit_print();
void emit_neg();
void emit_not();
void emit_open_paren();
void emit_close_paren();
#endif #endif

View File

@ -1,258 +1,304 @@
#include "../../emit.h" #include "../../emit.h"
#include <stdio.h> #include <stdio.h>
ExpressionConfig void
expression_config() c_prolog()
{ {
return INFIX;
}
OutputConfig
output_config()
{
return TEXT;
} }
void void
prolog() c_epilogue()
{ {
} }
void void
epilogue() c_emit_add()
{
}
void
emit_add()
{ {
printf("+ "); printf("+ ");
} }
void void
emit_sub() c_emit_sub()
{ {
printf("- "); printf("- ");
} }
void void
emit_mul() c_emit_mul()
{ {
printf("* "); printf("* ");
} }
void void
emit_div() c_emit_div()
{ {
printf("/ "); printf("/ ");
} }
void void
emit_lt() c_emit_lt()
{ {
printf("< "); printf("< ");
} }
void void
emit_le() c_emit_le()
{ {
printf("<= "); printf("<= ");
} }
void void
emit_gt() c_emit_gt()
{ {
printf("> "); printf("> ");
} }
void void
emit_ge() c_emit_ge()
{ {
printf(">= "); printf(">= ");
} }
void void
emit_ne() c_emit_ne()
{ {
printf("!= "); printf("!= ");
} }
void void
emit_eq() c_emit_eq()
{ {
printf("== "); printf("== ");
} }
void void
emit_false() c_emit_false()
{ {
printf("false "); printf("false ");
} }
void void
emit_true() c_emit_true()
{ {
printf("true "); printf("true ");
} }
void void
emit_nil() c_emit_nil()
{ {
printf("NULL "); printf("NULL ");
} }
void void
emit_neg() c_emit_neg()
{ {
printf("-"); printf("-");
} }
void void
emit_not() c_emit_not()
{ {
printf("!"); printf("!");
} }
void void
emit_void() c_emit_void()
{ {
} }
void void
emit_bool_type() c_emit_bool_type()
{ {
} }
void void
emit_byte_type() c_emit_byte_type()
{ {
} }
void void
emit_int_type() c_emit_int_type()
{ {
} }
void void
emit_nat_type() c_emit_nat_type()
{ {
} }
void void
emit_real_type() c_emit_real_type()
{ {
} }
void void
emit_str_type() c_emit_str_type()
{ {
} }
void void
emit_u8_type() c_emit_u8_type()
{ {
} }
void void
emit_i8_type() c_emit_i8_type()
{ {
} }
void void
emit_i16_type() c_emit_i16_type()
{ {
} }
void void
emit_u16_type() c_emit_u16_type()
{ {
} }
void void
emit_i32_type() c_emit_i32_type()
{ {
} }
void void
emit_u32_type() c_emit_u32_type()
{ {
} }
void void
emit_f32_type() c_emit_f32_type()
{ {
} }
void void
emit_int(const char *str, i32 length) c_emit_int(const char *str, i32 length)
{ {
printf("%.*s ", length, str); printf("%.*s ", length, str);
} }
void void
emit_nat(const char *str, i32 length) c_emit_nat(const char *str, i32 length)
{ {
printf("%.*s ", length, str); printf("%.*s ", length, str);
} }
void void
emit_real(const char *str, i32 length) c_emit_real(const char *str, i32 length)
{ {
printf("%.*s ", length, str); printf("%.*s ", length, str);
} }
void void
emit_str(const char *str, i32 length) c_emit_byte(const char *str, i32 length)
{ {
printf("%.*s ", length, str); printf("%.*s ", length, str);
} }
void void
emit_array() c_emit_str(const char *str, i32 length)
{
printf("%.*s ", length, str);
}
void
c_emit_array()
{ {
} }
void void
emit_function() c_emit_function()
{ {
} }
void void
emit_plex() c_emit_plex()
{ {
} }
void void
emit_method() c_emit_method()
{ {
} }
void void
emit_trait() c_emit_trait()
{ {
} }
void void
emit_const() c_emit_const()
{ {
} }
void void
emit_print() c_emit_print()
{ {
printf("printf(\"%%s\", "); printf("printf(\"%%s\", ");
} }
void void
emit_open_paren() c_emit_open_paren()
{ {
printf("("); printf("(");
} }
void void
emit_close_paren() c_emit_close_paren()
{ {
printf(")"); printf(")");
} }
Emitter
c_emitter()
{
return (Emitter){
INFIX,
TEXT,
c_prolog,
c_epilogue,
c_emit_add,
c_emit_sub,
c_emit_mul,
c_emit_div,
c_emit_lt,
c_emit_le,
c_emit_gt,
c_emit_ge,
c_emit_ne,
c_emit_eq,
c_emit_false,
c_emit_true,
c_emit_nil,
c_emit_void,
c_emit_int,
c_emit_nat,
c_emit_real,
c_emit_byte,
c_emit_str,
c_emit_bool_type,
c_emit_byte_type,
c_emit_int_type,
c_emit_nat_type,
c_emit_real_type,
c_emit_str_type,
c_emit_u8_type,
c_emit_i8_type,
c_emit_i16_type,
c_emit_u16_type,
c_emit_i32_type,
c_emit_u32_type,
c_emit_f32_type,
c_emit_array,
c_emit_function,
c_emit_plex,
c_emit_method,
c_emit_trait,
c_emit_const,
c_emit_print,
c_emit_neg,
c_emit_not,
c_emit_open_paren,
c_emit_close_paren,
};
}

346
emit/uxn/emit.c Normal file
View File

@ -0,0 +1,346 @@
#include "../../emit.h"
#include <stdio.h>
#include <stdlib.h>
#define UXN_OP_2 (1 << 5)
#define UXN_OP_R (1 << 6)
#define UXN_OP_K (1 << 7)
enum uxn_opcode {
/* Stack I */ /* Logic */ /* Memory I */ /* Arithmetic*/
BRK = 0x00, EQU = 0x08, LDZ = 0x10, ADD = 0x18,
INC = 0x01, NEQ = 0x09, STZ = 0x11, SUB = 0x19,
POP = 0x02, GTH = 0x0A, LDR = 0x12, MUL = 0x1A,
NIP = 0x03, LTH = 0x0B, STR = 0x13, DIV = 0x1B,
/* Stack II */ /* Stash */ /* Memory II */ /* Bitwise */
SWP = 0x04, JMP = 0x0C, LDA = 0x14, AND = 0x1C,
ROT = 0x05, JCN = 0x0D, STA = 0x15, ORA = 0x1D,
DUP = 0x06, JSR = 0x0E, DEI = 0x16, EOR = 0x1E,
OVR = 0x07, STH = 0x0F, DEO = 0x17, SFT = 0x1F,
LIT = 0x80, JCI = 0x20, JMI = 0x40, JSI = 0x60,
};
/*
https://rosettacode.org/wiki/Bitwise_operations#Uxntal
%not { #ff EOR }
%and { AND }
%or { ORA }
%xor { EOR }
%shl { #40 SFT SFT }
%shr { SFT }
%rol { #40 SFT #00 ROT ROT SFT2 ORA }
%ror { SWP #00 ROT SFT2 ORA }
*/
void
uxn_prolog()
{
}
void
uxn_epilogue()
{
}
void
uxn_emit_add()
{
printf("ADD2 ");
}
void
uxn_emit_sub()
{
printf("SUB2 ");
}
void
uxn_emit_mul()
{
printf("MUL2 ");
}
void
uxn_emit_div()
{
printf("DIV2 ");
}
void
uxn_emit_lt()
{
printf("LTH2 ");
}
void
uxn_emit_le()
{
printf("ROT SWP LTH ?{ LTH #00 EQU JMPr } GTH JMPr ");
}
void
uxn_emit_gt()
{
printf("GTH2 ");
}
void
uxn_emit_ge()
{
printf("ROT SWP GTH ?{ GTH #00 EQU JMPr } LTH JMPr ");
}
void
uxn_emit_ne()
{
printf("NEQ2 ");
}
void
uxn_emit_eq()
{
printf("EQU2 ");
}
void
uxn_emit_false()
{
printf("#0000 ");
}
void
uxn_emit_true()
{
printf("#0001 ");
}
void
uxn_emit_nil()
{
printf("#0000 ");
}
void
uxn_emit_neg()
{
printf("#0000 SUB2 ");
}
void
uxn_emit_not()
{
printf("#FFFF EOR2 ");
}
void
uxn_emit_void()
{
}
void
uxn_emit_bool_type()
{
}
void
uxn_emit_byte_type()
{
}
void
uxn_emit_int_type()
{
}
void
uxn_emit_nat_type()
{
}
void
uxn_emit_real_type()
{
}
void
uxn_emit_str_type()
{
}
void
uxn_emit_u8_type()
{
}
void
uxn_emit_i8_type()
{
}
void
uxn_emit_i16_type()
{
}
void
uxn_emit_u16_type()
{
}
void
uxn_emit_i32_type()
{
}
void
uxn_emit_u32_type()
{
}
void
uxn_emit_f32_type()
{
}
void
uxn_emit_int(const char *str, i32 length)
{
i32 i = (i32)strtol(str, nil, 10);
printf("#%04x ", i);
USED(length);
}
void
uxn_emit_nat(const char *str, i32 length)
{
u32 i = (u32)strtol(str, nil, 10);
printf("#%04x ", i);
USED(length);
}
void
uxn_emit_real(const char *str, i32 length)
{
USED(str);
USED(length);
/// TODO: implement this
}
void
uxn_emit_byte(const char *str, i32 length)
{
u8 i = (u8)strtol(str, nil, 10);
printf("#%04x ", i);
USED(length);
}
void
uxn_emit_str(const char *str, i32 length)
{
printf("\"%.*s ", length, str);
}
void
uxn_emit_array()
{
}
void
uxn_emit_function()
{
}
void
uxn_emit_plex()
{
}
void
uxn_emit_method()
{
}
void
uxn_emit_trait()
{
}
void
uxn_emit_const()
{
}
void
uxn_emit_print()
{
printf("#18 DEO ");
}
void
uxn_emit_open_paren()
{
}
void
uxn_emit_close_paren()
{
}
Emitter
uxn_emitter()
{
return (Emitter){
POSTFIX,
BINARY,
uxn_prolog,
uxn_epilogue,
uxn_emit_add,
uxn_emit_sub,
uxn_emit_mul,
uxn_emit_div,
uxn_emit_lt,
uxn_emit_le,
uxn_emit_gt,
uxn_emit_ge,
uxn_emit_ne,
uxn_emit_eq,
uxn_emit_false,
uxn_emit_true,
uxn_emit_nil,
uxn_emit_void,
uxn_emit_int,
uxn_emit_nat,
uxn_emit_real,
uxn_emit_byte,
uxn_emit_str,
uxn_emit_bool_type,
uxn_emit_byte_type,
uxn_emit_int_type,
uxn_emit_nat_type,
uxn_emit_real_type,
uxn_emit_str_type,
uxn_emit_u8_type,
uxn_emit_i8_type,
uxn_emit_i16_type,
uxn_emit_u16_type,
uxn_emit_i32_type,
uxn_emit_u32_type,
uxn_emit_f32_type,
uxn_emit_array,
uxn_emit_function,
uxn_emit_plex,
uxn_emit_method,
uxn_emit_trait,
uxn_emit_const,
uxn_emit_print,
uxn_emit_neg,
uxn_emit_not,
uxn_emit_open_paren,
uxn_emit_close_paren,
};
}

View File

@ -1,257 +0,0 @@
#include "../../emit.h"
#include <stdio.h>
ExpressionConfig
expression_config()
{
return POSTFIX;
}
OutputConfig
output_config()
{
return TEXT;
}
void
prolog()
{
}
void
epilogue()
{
}
void
emit_add()
{
printf("+ ");
}
void
emit_sub()
{
printf("- ");
}
void
emit_mul()
{
printf("* ");
}
void
emit_div()
{
printf("/ ");
}
void
emit_lt()
{
printf("< ");
}
void
emit_le()
{
printf("<= ");
}
void
emit_gt()
{
printf("> ");
}
void
emit_ge()
{
printf(">= ");
}
void
emit_ne()
{
printf("!= ");
}
void
emit_eq()
{
printf("== ");
}
void
emit_false()
{
printf("false ");
}
void
emit_true()
{
printf("true ");
}
void
emit_nil()
{
printf("NULL ");
}
void
emit_neg()
{
printf("-");
}
void
emit_not()
{
printf("!");
}
void
emit_void()
{
}
void
emit_bool_type()
{
}
void
emit_byte_type()
{
}
void
emit_int_type()
{
}
void
emit_nat_type()
{
}
void
emit_real_type()
{
}
void
emit_str_type()
{
}
void
emit_u8_type()
{
}
void
emit_i8_type()
{
}
void
emit_i16_type()
{
}
void
emit_u16_type()
{
}
void
emit_i32_type()
{
}
void
emit_u32_type()
{
}
void
emit_f32_type()
{
}
void
emit_int(const char *str, i32 length)
{
printf("%.*s ", length, str);
}
void
emit_nat(const char *str, i32 length)
{
printf("%.*s ", length, str);
}
void
emit_real(const char *str, i32 length)
{
printf("%.*s ", length, str);
}
void
emit_str(const char *str, i32 length)
{
printf("%.*s ", length, str);
}
void
emit_array()
{
}
void
emit_function()
{
}
void
emit_plex()
{
}
void
emit_method()
{
}
void
emit_trait()
{
}
void
emit_const()
{
}
void
emit_print()
{
printf("printf(\"%%s\", ");
}
void
emit_open_paren()
{
printf("(");
}
void
emit_close_paren()
{
printf(")");
}

View File

@ -132,8 +132,9 @@ skip_whitespace()
static TokenType static TokenType
check_keyword(i32 start, i32 length, const char *rest, TokenType type) check_keyword(i32 start, i32 length, const char *rest, TokenType type)
{ {
if(lexer.current - lexer.start == start + length && i32 s1 = lexer.current - lexer.start;
sleq(lexer.start + start, rest, length) == 0) { i32 s2 = start + length;
if(s1 == s2 && sleq(lexer.start + start, rest, length)) {
return type; return type;
} }

View File

@ -1,6 +1,7 @@
#include "parser.h" #include "parser.h"
#include "emit.h" #include "emit.h"
Emitter emitter;
Parser parser; Parser parser;
/**************************************************** /****************************************************
@ -116,43 +117,48 @@ binary()
TokenType operatorType = parser.previous.type; TokenType operatorType = parser.previous.type;
ParseRule *rule = get_rule(operatorType); ParseRule *rule = get_rule(operatorType);
if (emitter.notation == POSTFIX) {
parse_precedence((Precedence)(rule->precedence + 1));
}
switch(operatorType) { switch(operatorType) {
case TOKEN_BANG_EQ: case TOKEN_BANG_EQ:
emit_ne(); emitter.emit_ne();
break; break;
case TOKEN_EQ_EQ: case TOKEN_EQ_EQ:
emit_eq(); emitter.emit_eq();
break; break;
case TOKEN_GT: case TOKEN_GT:
emit_ge(); emitter.emit_ge();
break; break;
case TOKEN_GTE: case TOKEN_GTE:
emit_ge(); emitter.emit_ge();
break; break;
case TOKEN_LT: case TOKEN_LT:
emit_lt(); emitter.emit_lt();
break; break;
case TOKEN_LTE: case TOKEN_LTE:
emit_le(); emitter.emit_le();
break; break;
case TOKEN_PLUS: case TOKEN_PLUS:
emit_add(); emitter.emit_add();
break; break;
case TOKEN_MINUS: case TOKEN_MINUS:
emit_sub(); emitter.emit_sub();
break; break;
case TOKEN_STAR: case TOKEN_STAR:
emit_mul(); emitter.emit_mul();
break; break;
case TOKEN_SLASH: case TOKEN_SLASH:
emit_div(); emitter.emit_div();
break; break;
default: default:
return; return;
} }
/* Move to above switch statement for postfix */ if (emitter.notation == INFIX) {
parse_precedence((Precedence)(rule->precedence + 1)); parse_precedence((Precedence)(rule->precedence + 1));
}
} }
static void static void
@ -160,13 +166,13 @@ literal()
{ {
switch(parser.previous.type) { switch(parser.previous.type) {
case TOKEN_KEYWORD_FALSE: case TOKEN_KEYWORD_FALSE:
emit_false(); emitter.emit_false();
break; break;
case TOKEN_KEYWORD_TRUE: case TOKEN_KEYWORD_TRUE:
emit_true(); emitter.emit_true();
break; break;
case TOKEN_KEYWORD_NIL: case TOKEN_KEYWORD_NIL:
emit_nil(); emitter.emit_nil();
break; break;
default: default:
return; return;
@ -183,25 +189,25 @@ static void
declaration() declaration()
{ {
if(match(TOKEN_TYPE_INT)) { if(match(TOKEN_TYPE_INT)) {
emit_int_type(); emitter.emit_int_type();
} else if(match(TOKEN_TYPE_NAT)) { } else if(match(TOKEN_TYPE_NAT)) {
emit_nat_type(); emitter.emit_nat_type();
} else if(match(TOKEN_TYPE_REAL)) { } else if(match(TOKEN_TYPE_REAL)) {
emit_real_type(); emitter.emit_real_type();
} else if(match(TOKEN_TYPE_STR)) { } else if(match(TOKEN_TYPE_STR)) {
emit_str_type(); emitter.emit_str_type();
} else if(match(TOKEN_TYPE_BOOL)) { } else if(match(TOKEN_TYPE_BOOL)) {
emit_bool_type(); emitter.emit_bool_type();
} else if(match(TOKEN_TYPE_BYTE)) { } else if(match(TOKEN_TYPE_BYTE)) {
emit_byte_type(); emitter.emit_byte_type();
} else if(match(TOKEN_TYPE_U8)) { } else if(match(TOKEN_TYPE_U8)) {
emit_u8_type(); emitter.emit_u8_type();
} else if(match(TOKEN_TYPE_I8)) { } else if(match(TOKEN_TYPE_I8)) {
emit_i8_type(); emitter.emit_i8_type();
} else if(match(TOKEN_TYPE_U16)) { } else if(match(TOKEN_TYPE_U16)) {
emit_u16_type(); emitter.emit_u16_type();
} else if(match(TOKEN_TYPE_I16)) { } else if(match(TOKEN_TYPE_I16)) {
emit_i16_type(); emitter.emit_i16_type();
} else if(match(TOKEN_IDENTIFIER)) { } else if(match(TOKEN_IDENTIFIER)) {
/** /**
* maybe a Plex? * maybe a Plex?
@ -213,56 +219,67 @@ declaration()
statement(); statement();
} }
static void print_statement() {
expression();
consume(TOKEN_SEMICOLON);
emitter.emit_print();
}
static void static void
statement() statement()
{ {
if(match(TOKEN_KEYWORD_PRINT)) if(match(TOKEN_KEYWORD_PRINT)) {
emit_print(); print_statement();
else } else {
expression(); expression();
}
} }
static void static void
grouping() grouping()
{ {
emit_open_paren(); emitter.emit_open_paren();
expression(); expression();
emit_close_paren(); emitter.emit_close_paren();
consume(TOKEN_RPAREN); consume(TOKEN_RPAREN);
} }
static void static void
number() number()
{ {
emit_int(parser.previous.start, parser.previous.length); emitter.emit_int(parser.previous.start, parser.previous.length);
} }
static void static void
string() string()
{ {
emit_str(parser.previous.start, parser.previous.length); emitter.emit_str(parser.previous.start, parser.previous.length);
} }
static void static void
unary() unary()
{ {
TokenType operatorType = parser.previous.type; TokenType operatorType = parser.previous.type;
if (emitter.notation == POSTFIX) {
parse_precedence(PREC_UNARY);
}
switch(operatorType) { switch(operatorType) {
case TOKEN_MINUS: case TOKEN_MINUS:
emit_neg(); emitter.emit_neg();
break; break;
case TOKEN_BANG: case TOKEN_BANG:
emit_not(); emitter.emit_not();
break; break;
default: default:
return; return;
} }
/* Move to above switch statement for postfix */ if (emitter.notation == INFIX) {
parse_precedence(PREC_UNARY); parse_precedence(PREC_UNARY);
}
} }
ParseRule rules[] = { ParseRule rules[] = {
@ -375,16 +392,17 @@ get_rule(TokenType type)
} }
bool bool
compile(char *source) compile(Emitter e, char *source)
{ {
emitter = e;
init_lexer(source); init_lexer(source);
advance(); advance();
prolog(); emitter.prolog();
while(!match(TOKEN_EOF)) declaration(); while(!match(TOKEN_EOF)) declaration();
epilogue(); emitter.epilogue();
return true; return true;
} }

View File

@ -79,9 +79,6 @@ struct parser_s {
Token previous; Token previous;
}; };
bool compile(char *source); bool compile(Emitter e, char *source);
extern void emit_return();
extern void emit_constant();
#endif #endif

View File

@ -1 +1 @@
print((1.0 + 1.0) as str); print((122 - 32)); // prints ascii `Z`