Compare commits
3 Commits
ed933356d2
...
d64f7c86c4
| Author | SHA1 | Date |
|---|---|---|
|
|
d64f7c86c4 | |
|
|
65433ea629 | |
|
|
3a44877465 |
42
compiler.c
42
compiler.c
|
|
@ -296,7 +296,7 @@ calculate_strides(List *dims, List *strides)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Symbol*
|
||||
define_array(void)
|
||||
{
|
||||
i32 size = 0, n = 0, flat_array_length = 1;
|
||||
|
|
@ -329,13 +329,7 @@ define_array(void)
|
|||
calculate_strides(dims, strides);
|
||||
array->args = dims;
|
||||
array->fields = strides;
|
||||
}
|
||||
|
||||
void
|
||||
define_string(void)
|
||||
{
|
||||
scope_add_symbol(parser->current.start, parser->current.length, SYMBOL_STR,
|
||||
0);
|
||||
return array;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -357,13 +351,6 @@ build_symbol_table(char *source)
|
|||
define_plex();
|
||||
} else if(match(TOKEN_KEYWORD_TRAIT)) {
|
||||
define_trait();
|
||||
} else if(parser->previous.type != TOKEN_KEYWORD_AS &&
|
||||
match(TOKEN_TYPE_STR)) {
|
||||
define_string();
|
||||
} else if(parser->current.type >= TOKEN_TYPE_I8 &&
|
||||
parser->current.type <= TOKEN_TYPE_PTR) {
|
||||
advance();
|
||||
if(check(TOKEN_LBRACKET)) define_array();
|
||||
} else {
|
||||
/* in binary bytecode output mode we need to count the bytes here */
|
||||
/* otherwise ignore everything */
|
||||
|
|
@ -387,9 +374,10 @@ variable_declaration(Symbol *def)
|
|||
Symbol *variable;
|
||||
List *array_literal;
|
||||
|
||||
if(tt == TOKEN_TYPE_STR) {
|
||||
variable = scope_get_symbol(parser->current_scope, parser->current.start,
|
||||
parser->current.length);
|
||||
if(!def && tt == TOKEN_TYPE_STR) {
|
||||
variable = scope_add_symbol(parser->current.start, parser->current.length, SYMBOL_STR,
|
||||
0);
|
||||
|
||||
if(!variable) {
|
||||
emitter->error("cannot find str symbol", 23, parser->current.line);
|
||||
return 0;
|
||||
|
|
@ -408,12 +396,8 @@ variable_declaration(Symbol *def)
|
|||
return emitter->get_size(st);
|
||||
}
|
||||
|
||||
if(parser->current.type == TOKEN_LBRACKET) {
|
||||
while(!check(TOKEN_RBRACKET)) advance();
|
||||
advance();
|
||||
|
||||
variable = scope_get_symbol(parser->current_scope, parser->current.start,
|
||||
parser->current.length);
|
||||
if(!def && parser->current.type == TOKEN_LBRACKET) {
|
||||
variable = define_array();
|
||||
if(!variable) {
|
||||
emitter->error("cannot find array symbol", 25, parser->current.line);
|
||||
return 0;
|
||||
|
|
@ -459,7 +443,7 @@ variable_declaration(Symbol *def)
|
|||
if(def) {
|
||||
List_push(arena, def->args, variable, sizeof(Symbol));
|
||||
} else {
|
||||
emitter->emit_type(arena, code, variable, variable->scope);
|
||||
emitter->emit_type(arena, code, variable);
|
||||
parser->current_type = st;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -478,7 +462,7 @@ variable_declaration(Symbol *def)
|
|||
if(match(TOKEN_EQ)) {
|
||||
emitter->emit_set_value(arena, code);
|
||||
expression();
|
||||
emitter->emit_constant(arena, code, variable, variable->scope);
|
||||
emitter->emit_constant(arena, code, variable);
|
||||
}
|
||||
|
||||
consume(TOKEN_SEMICOLON);
|
||||
|
|
@ -691,9 +675,9 @@ variable(void)
|
|||
parser->current_type = sym->type;
|
||||
if(match(TOKEN_EQ)) {
|
||||
expression();
|
||||
emitter->emit_set_variable(arena, code, sym, sym->scope);
|
||||
emitter->emit_set_variable(arena, code, sym);
|
||||
} else {
|
||||
emitter->emit_variable(arena, code, sym, sym->scope);
|
||||
emitter->emit_variable(arena, code, sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1125,7 +1109,7 @@ emit_program(char *source)
|
|||
|
||||
while(!match(TOKEN_EOF)) declaration();
|
||||
|
||||
/*emitter->epilogue(arena, code);*/
|
||||
emitter->epilogue(arena, code);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
9
emit.h
9
emit.h
|
|
@ -10,7 +10,6 @@ typedef void (*ErrorMsg)(const char *str, i32 length, i32 line);
|
|||
typedef void (*SymbolEmit)(Arena *a, List *out, Symbol *sym);
|
||||
typedef void (*VoidArgEmit)(Arena *a, List *out);
|
||||
typedef void (*StrArgEmit)(Arena *a, List *out, const char *str, i32 length);
|
||||
typedef void (*VarEmit)(Arena *a, List *out, Symbol *sym, bool local);
|
||||
typedef void (*MultipleEmit)(Arena *a, List *out, Symbol *sym, List* in);
|
||||
typedef void (*I32ArgEmit)(Arena *a, List *out, i32 val);
|
||||
typedef void (*U32ArgEmit)(Arena *a, List *out, u32 ptr);
|
||||
|
|
@ -45,7 +44,7 @@ struct emitter_s {
|
|||
StrArgEmit emit_real;
|
||||
StrArgEmit emit_byte;
|
||||
RawEmit emit_str;
|
||||
VarEmit emit_type;
|
||||
SymbolEmit emit_type;
|
||||
MultipleEmit emit_array;
|
||||
SymbolEmit emit_function;
|
||||
VoidArgEmit emit_plex;
|
||||
|
|
@ -57,9 +56,9 @@ struct emitter_s {
|
|||
VoidArgEmit emit_not;
|
||||
VoidArgEmit emit_open_paren;
|
||||
VoidArgEmit emit_close_paren;
|
||||
VarEmit emit_constant;
|
||||
VarEmit emit_variable;
|
||||
VarEmit emit_set_variable;
|
||||
SymbolEmit emit_constant;
|
||||
SymbolEmit emit_variable;
|
||||
SymbolEmit emit_set_variable;
|
||||
VoidArgEmit emit_write;
|
||||
VoidArgEmit emit_read;
|
||||
VoidArgEmit emit_open;
|
||||
|
|
|
|||
|
|
@ -583,7 +583,6 @@ uxn_mem(u32 a)
|
|||
void
|
||||
uxn_prolog(Arena *a, List *out)
|
||||
{
|
||||
/*StrBuf_append(a, out, "|100\n\tLIT2r 0000 main_ POP2r BRK\n\n");*/
|
||||
StrBuf_append(a, out, "|100\n\tLIT2r 0000\n\n");
|
||||
}
|
||||
|
||||
|
|
@ -747,17 +746,25 @@ uxn_get_size(SymbolType t)
|
|||
return 4;
|
||||
case SYMBOL_F32:
|
||||
return 4;
|
||||
default:
|
||||
break;
|
||||
case SYMBOL_ARRAY:
|
||||
case SYMBOL_FUNCTION:
|
||||
case SYMBOL_PLEX:
|
||||
case SYMBOL_METHOD:
|
||||
case SYMBOL_TRAIT:
|
||||
case SYMBOL_CONST:
|
||||
return 2;
|
||||
case SYMBOL_UNDEFINED:
|
||||
case SYMBOL_VOID:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_type(Arena *a, List *out, Symbol *sym, bool local)
|
||||
uxn_emit_type(Arena *a, List *out, Symbol *sym)
|
||||
{
|
||||
if(local) {
|
||||
if(sym->scope) {
|
||||
if(sym->ref) {
|
||||
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2\n", sym->ref);
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
|
|
@ -812,15 +819,36 @@ uxn_emit_byte(Arena *a, List *out, const char *str, i32 length)
|
|||
void
|
||||
uxn_emit_char(Arena *a, List *out, const char *str, i32 length)
|
||||
{
|
||||
if (str[1] == '\\') {
|
||||
char c = ' ';
|
||||
switch(str[2]) {
|
||||
case 'n':
|
||||
c = '\n';
|
||||
break;
|
||||
case 't':
|
||||
c = '\t';
|
||||
break;
|
||||
case 'r':
|
||||
c = '\r';
|
||||
break;
|
||||
case '\\':
|
||||
case '"':
|
||||
case '\'':
|
||||
break;
|
||||
}
|
||||
sprintf(uxn_temp_strbuf, "#%02x ", c);
|
||||
} else {
|
||||
sprintf(uxn_temp_strbuf, "#%02x ", (char)str[1]);
|
||||
}
|
||||
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
USED(length);
|
||||
}
|
||||
|
||||
void
|
||||
uxn_emit_constant(Arena *a, List *out, Symbol *sym, bool local)
|
||||
uxn_emit_constant(Arena *a, List *out, Symbol *sym)
|
||||
{
|
||||
if(local) {
|
||||
if(sym->scope) {
|
||||
if(sym->ref) {
|
||||
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2\n", sym->ref);
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
|
|
@ -1120,9 +1148,9 @@ uxn_emit_close_paren(Arena *a, List *out)
|
|||
}
|
||||
|
||||
void
|
||||
uxn_emit_variable(Arena *a, List *out, Symbol *sym, bool local)
|
||||
uxn_emit_variable(Arena *a, List *out, Symbol *sym)
|
||||
{
|
||||
if(local) {
|
||||
if(sym->scope) {
|
||||
if(sym->ref) {
|
||||
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2 ", sym->ref);
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
|
|
@ -1137,9 +1165,9 @@ uxn_emit_variable(Arena *a, List *out, Symbol *sym, bool local)
|
|||
}
|
||||
|
||||
void
|
||||
uxn_emit_set_variable(Arena *a, List *out, Symbol *sym, bool local)
|
||||
uxn_emit_set_variable(Arena *a, List *out, Symbol *sym)
|
||||
{
|
||||
if(local) {
|
||||
if(sym->scope) {
|
||||
if(sym->ref) {
|
||||
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2 ", sym->ref);
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
|
|
@ -1417,8 +1445,18 @@ uxn_emit_halt(Arena *a, List *out)
|
|||
void
|
||||
uxn_emit_deref_prolog(Arena *a, List *out, Symbol *sym)
|
||||
{
|
||||
if(sym->scope) {
|
||||
if(sym->ref) {
|
||||
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 ", sym->ref);
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
} else {
|
||||
sprintf(uxn_temp_strbuf, "\tSTH2kr ");
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
}
|
||||
} else {
|
||||
sprintf(uxn_temp_strbuf, ";%.*s ", sym->name_length, sym->name);
|
||||
StrBuf_append(a, out, uxn_temp_strbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
4
lexer.c
4
lexer.c
|
|
@ -319,9 +319,9 @@ identifierType(void)
|
|||
if(lexer.current - lexer.start > 1) {
|
||||
switch(lexer.start[1]) {
|
||||
case 'y':
|
||||
return check_keyword(2, 2, "te", TOKEN_TYPE_U8);
|
||||
return check_keyword(2, 2, "te", TOKEN_TYPE_BYTE);
|
||||
case 'o':
|
||||
return check_keyword(2, 2, "ol", TOKEN_TYPE_U8);
|
||||
return check_keyword(2, 2, "ol", TOKEN_TYPE_BOOL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,206 @@
|
|||
const int I16_MIN = -32768;
|
||||
const int I16_MAX = 32767;
|
||||
const nat U16_MAX = 65535;
|
||||
|
||||
byte[10000] heap;
|
||||
nat heap_allocated = 0;
|
||||
|
||||
function malloc(nat size) ref byte[] {
|
||||
nat pos = heap_allocated;
|
||||
heap_allocated = heap_allocated + size;
|
||||
return ref heap[pos];
|
||||
}
|
||||
|
||||
function free() {
|
||||
heap_allocated = 0;
|
||||
}
|
||||
|
||||
function memcpy(ref byte[] to, ref byte[] from, nat length) {
|
||||
for (nat i = 0; i < length; i++) {
|
||||
to[i] = from[i];
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
function mallocpy(ref byte[] from, nat length) ref byte[] {
|
||||
ref byte[] ptr = malloc(length);
|
||||
for (nat i = 0; i < length; i++) {
|
||||
ptr[i] = from[i];
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print with a newline
|
||||
*/
|
||||
function pln(str string) {
|
||||
for (byte c in string) {
|
||||
write = c;
|
||||
}
|
||||
write = '\n';
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatinates 2 strings
|
||||
*/
|
||||
function strcat(str src1, str src2) str {
|
||||
str result = malloc(src1.length + src2.length);
|
||||
memcpy(ref result[0], ref src1[0]);
|
||||
memcpy((ref result[0] + src1.length), ref src2[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* finds index of string, -1 if not found
|
||||
*/
|
||||
function stridx(str haystack, char needle) int {
|
||||
int i = -1;
|
||||
for (char c in haystack) {
|
||||
i = i + 1;
|
||||
if (c == needle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if 2 strings are equal
|
||||
*/
|
||||
function streq(str src1, str src2) bool {
|
||||
if (src1.length != src2.length) return false;
|
||||
for (int i=0; src1.length; i++) {
|
||||
if (src1[i] != src2[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Slice string
|
||||
*/
|
||||
function slice(str src, int start, int stop) str {
|
||||
int len = stop - start;
|
||||
str result = malloc(len);
|
||||
for (int i=start; i<stop; i++) {
|
||||
result[i] = src[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* int to string
|
||||
*/
|
||||
function itos(int src) str {
|
||||
byte buffer[6];
|
||||
nat i = 6;
|
||||
bool neg = n < 0;
|
||||
|
||||
if (neg) n = -n;
|
||||
|
||||
do {
|
||||
buffer[--i] = '0' + n mod 10;
|
||||
n /= 10;
|
||||
} while(n > 0);
|
||||
|
||||
if(neg) buffer[--i] = '-';
|
||||
|
||||
str result = malloc(6 - i);
|
||||
memcpy(result, &buffer[0] + i, 6 - i);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* nat to string
|
||||
*/
|
||||
function ntos(nat src) str {
|
||||
byte buffer[5];
|
||||
nat i = 5;
|
||||
|
||||
do {
|
||||
buffer[--i] = '0' + n mod 10;
|
||||
n /= 10;
|
||||
} while(n > 0);
|
||||
|
||||
str result = malloc(5 - i);
|
||||
memcpy(result, &buffer[0] + i, 5 - i);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* real to string
|
||||
*/
|
||||
function rtos(real src) str {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* string to int
|
||||
*/
|
||||
function stoi(str src) int {
|
||||
bool neg = false;
|
||||
int n = 0;
|
||||
nat idx = 0;
|
||||
|
||||
while (is_space(src[idx])) {
|
||||
if (length-- == 0) { return n; }
|
||||
idx = idx + 1;
|
||||
}
|
||||
|
||||
if (src[idx] == '-') {
|
||||
neg = true;
|
||||
if (length-- == 0) { return n; }
|
||||
idx = idx + 1;
|
||||
}
|
||||
|
||||
while (is_digit(src[idx]) and length-- > 0) {
|
||||
int digit = (src[idx] - '0' as int);
|
||||
idx = idx + 1;
|
||||
|
||||
if (neg) {
|
||||
if (n < (I16_MIN / 10) or (n == (I16_MIN / 10) and digit > -(I16_MIN mod 10))) {
|
||||
return I16_MIN;
|
||||
}
|
||||
n = n * 10 - digit;
|
||||
} else {
|
||||
if (n > (I16_MAX / 10) or (n == (I16_MAX / 10) and digit > (I16_MAX mod 10))) {
|
||||
return I16_MAX;
|
||||
}
|
||||
n = n * 10 + digit;
|
||||
}
|
||||
}
|
||||
|
||||
return neg ? -n : n;
|
||||
}
|
||||
|
||||
/**
|
||||
* string to nat
|
||||
*/
|
||||
function ston(str src) nat {
|
||||
nat n = 0;
|
||||
nat idx = 0;
|
||||
|
||||
while (is_space(src[idx])) {
|
||||
if (length-- == 0) { return n; }
|
||||
idx = idx + 1;
|
||||
}
|
||||
|
||||
while (is_digit(src[idx]) and length-- > 0) {
|
||||
nat digit = (src[idx] - '0' as nat);
|
||||
idx = idx + 1;
|
||||
|
||||
if (n > (U16_MAX / 10) or (n == (U16_MAX / 10) and digit > (U16_MAX mod 10))) {
|
||||
return U16_MAX;
|
||||
}
|
||||
n = n * 10 + digit;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* string to real
|
||||
*/
|
||||
function stor(str src) real {
|
||||
|
||||
}
|
||||
128
test/str.ul
128
test/str.ul
|
|
@ -1,128 +0,0 @@
|
|||
/**
|
||||
* Constants
|
||||
*/
|
||||
const str nl = "\n";
|
||||
|
||||
/**
|
||||
* Print with a newline
|
||||
*/
|
||||
function pln(str string) {
|
||||
for (byte c in string) {
|
||||
putchar(c);
|
||||
}
|
||||
putchar(nl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatinates 2 strings
|
||||
*/
|
||||
function strcat(str src1, str src2) str {
|
||||
str result = malloc(src1.length + src2.length);
|
||||
memcpy(&result[0], &src1);
|
||||
memcpy((&result + src1.length), &src2);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* finds index of string, -1 if not found
|
||||
*/
|
||||
function stridx(str haystack, byte needle) int {
|
||||
int i = -1;
|
||||
for (byte c in haystack) {
|
||||
i = i + 1;
|
||||
if (c == needle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if 2 strings are equal
|
||||
*/
|
||||
function streq(str src1, str src2) bool {
|
||||
if (src1.length != src2.length) return false;
|
||||
for (int i=0; src1.length; i++) {
|
||||
if (src1[i] != src2[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Slice string
|
||||
*/
|
||||
function slice(str src, int start, int stop) str {
|
||||
int len = stop - start;
|
||||
str result = malloc(len);
|
||||
for (int i=start; i<stop; i++) {
|
||||
result[i] = src[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* int to string
|
||||
*/
|
||||
function itos(int src) str {
|
||||
byte buffer[6];
|
||||
nat i = 6;
|
||||
bool neg = n < 0;
|
||||
|
||||
if (neg) n = -n;
|
||||
|
||||
do {
|
||||
buffer[--i] = '0' + n % 10;
|
||||
n /= 10;
|
||||
} while(n > 0);
|
||||
|
||||
if(neg) buffer[--i] = '-';
|
||||
|
||||
str result = malloc(6 - i);
|
||||
memcpy(result, &buffer[0] + i, 6 - i);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* nat to string
|
||||
*/
|
||||
function ntos(nat src) str {
|
||||
byte buffer[5];
|
||||
nat i = 5;
|
||||
|
||||
do {
|
||||
buffer[--i] = '0' + n % 10;
|
||||
n /= 10;
|
||||
} while(n > 0);
|
||||
|
||||
str result = malloc(5 - i);
|
||||
memcpy(result, &buffer[0] + i, 5 - i);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* real to string
|
||||
*/
|
||||
function rtos(real src) str {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* string to int
|
||||
*/
|
||||
function stoi(str src) int {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* string to nat
|
||||
*/
|
||||
function ston(str src) nat {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* string to real
|
||||
*/
|
||||
function stor(str src) real {
|
||||
|
||||
}
|
||||
|
|
@ -1,13 +1,22 @@
|
|||
str hello = "hello World!\n";
|
||||
str msg = " damage inflicted!\n";
|
||||
str hello = "hello World!";
|
||||
str msg = " damage inflicted!";
|
||||
|
||||
if (msg[1] == 'd') {
|
||||
print("yes\n");
|
||||
pln("yes");
|
||||
}
|
||||
|
||||
print(msg.length as str);
|
||||
print(msg);
|
||||
pln(msg.length as str);
|
||||
pln(msg);
|
||||
|
||||
hello[0] = hello[0] - ' ';
|
||||
print(hello);
|
||||
pln(hello);
|
||||
halt;
|
||||
|
||||
function pln(str string) {
|
||||
nat i = 0;
|
||||
while (i < string.length) {
|
||||
write = string[i];
|
||||
i = i + 1;
|
||||
}
|
||||
write = '\n';
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue