Compare commits

..

3 Commits

Author SHA1 Message Date
zongor d64f7c86c4 remove old str 2026-07-06 18:39:27 -07:00
zongor 65433ea629 string test changes, add intial stdlib 2026-07-06 18:39:16 -07:00
zongor 3a44877465 WIP function array fixes 2026-07-06 18:38:56 -07:00
7 changed files with 292 additions and 184 deletions

View File

@ -296,7 +296,7 @@ calculate_strides(List *dims, List *strides)
} }
} }
void Symbol*
define_array(void) define_array(void)
{ {
i32 size = 0, n = 0, flat_array_length = 1; i32 size = 0, n = 0, flat_array_length = 1;
@ -329,13 +329,7 @@ define_array(void)
calculate_strides(dims, strides); calculate_strides(dims, strides);
array->args = dims; array->args = dims;
array->fields = strides; array->fields = strides;
} return array;
void
define_string(void)
{
scope_add_symbol(parser->current.start, parser->current.length, SYMBOL_STR,
0);
} }
void void
@ -357,13 +351,6 @@ build_symbol_table(char *source)
define_plex(); define_plex();
} else if(match(TOKEN_KEYWORD_TRAIT)) { } else if(match(TOKEN_KEYWORD_TRAIT)) {
define_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 { } else {
/* in binary bytecode output mode we need to count the bytes here */ /* in binary bytecode output mode we need to count the bytes here */
/* otherwise ignore everything */ /* otherwise ignore everything */
@ -387,9 +374,10 @@ variable_declaration(Symbol *def)
Symbol *variable; Symbol *variable;
List *array_literal; List *array_literal;
if(tt == TOKEN_TYPE_STR) { if(!def && tt == TOKEN_TYPE_STR) {
variable = scope_get_symbol(parser->current_scope, parser->current.start, variable = scope_add_symbol(parser->current.start, parser->current.length, SYMBOL_STR,
parser->current.length); 0);
if(!variable) { if(!variable) {
emitter->error("cannot find str symbol", 23, parser->current.line); emitter->error("cannot find str symbol", 23, parser->current.line);
return 0; return 0;
@ -408,12 +396,8 @@ variable_declaration(Symbol *def)
return emitter->get_size(st); return emitter->get_size(st);
} }
if(parser->current.type == TOKEN_LBRACKET) { if(!def && parser->current.type == TOKEN_LBRACKET) {
while(!check(TOKEN_RBRACKET)) advance(); variable = define_array();
advance();
variable = scope_get_symbol(parser->current_scope, parser->current.start,
parser->current.length);
if(!variable) { if(!variable) {
emitter->error("cannot find array symbol", 25, parser->current.line); emitter->error("cannot find array symbol", 25, parser->current.line);
return 0; return 0;
@ -459,7 +443,7 @@ variable_declaration(Symbol *def)
if(def) { if(def) {
List_push(arena, def->args, variable, sizeof(Symbol)); List_push(arena, def->args, variable, sizeof(Symbol));
} else { } else {
emitter->emit_type(arena, code, variable, variable->scope); emitter->emit_type(arena, code, variable);
parser->current_type = st; parser->current_type = st;
} }
} else { } else {
@ -478,7 +462,7 @@ variable_declaration(Symbol *def)
if(match(TOKEN_EQ)) { if(match(TOKEN_EQ)) {
emitter->emit_set_value(arena, code); emitter->emit_set_value(arena, code);
expression(); expression();
emitter->emit_constant(arena, code, variable, variable->scope); emitter->emit_constant(arena, code, variable);
} }
consume(TOKEN_SEMICOLON); consume(TOKEN_SEMICOLON);
@ -691,9 +675,9 @@ variable(void)
parser->current_type = sym->type; parser->current_type = sym->type;
if(match(TOKEN_EQ)) { if(match(TOKEN_EQ)) {
expression(); expression();
emitter->emit_set_variable(arena, code, sym, sym->scope); emitter->emit_set_variable(arena, code, sym);
} else { } 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(); while(!match(TOKEN_EOF)) declaration();
/*emitter->epilogue(arena, code);*/ emitter->epilogue(arena, code);
} }
bool bool

9
emit.h
View File

@ -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 (*SymbolEmit)(Arena *a, List *out, Symbol *sym);
typedef void (*VoidArgEmit)(Arena *a, List *out); typedef void (*VoidArgEmit)(Arena *a, List *out);
typedef void (*StrArgEmit)(Arena *a, List *out, const char *str, i32 length); 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 (*MultipleEmit)(Arena *a, List *out, Symbol *sym, List* in);
typedef void (*I32ArgEmit)(Arena *a, List *out, i32 val); typedef void (*I32ArgEmit)(Arena *a, List *out, i32 val);
typedef void (*U32ArgEmit)(Arena *a, List *out, u32 ptr); typedef void (*U32ArgEmit)(Arena *a, List *out, u32 ptr);
@ -45,7 +44,7 @@ struct emitter_s {
StrArgEmit emit_real; StrArgEmit emit_real;
StrArgEmit emit_byte; StrArgEmit emit_byte;
RawEmit emit_str; RawEmit emit_str;
VarEmit emit_type; SymbolEmit emit_type;
MultipleEmit emit_array; MultipleEmit emit_array;
SymbolEmit emit_function; SymbolEmit emit_function;
VoidArgEmit emit_plex; VoidArgEmit emit_plex;
@ -57,9 +56,9 @@ struct emitter_s {
VoidArgEmit emit_not; VoidArgEmit emit_not;
VoidArgEmit emit_open_paren; VoidArgEmit emit_open_paren;
VoidArgEmit emit_close_paren; VoidArgEmit emit_close_paren;
VarEmit emit_constant; SymbolEmit emit_constant;
VarEmit emit_variable; SymbolEmit emit_variable;
VarEmit emit_set_variable; SymbolEmit emit_set_variable;
VoidArgEmit emit_write; VoidArgEmit emit_write;
VoidArgEmit emit_read; VoidArgEmit emit_read;
VoidArgEmit emit_open; VoidArgEmit emit_open;

View File

@ -583,7 +583,6 @@ uxn_mem(u32 a)
void void
uxn_prolog(Arena *a, List *out) 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"); StrBuf_append(a, out, "|100\n\tLIT2r 0000\n\n");
} }
@ -747,17 +746,25 @@ uxn_get_size(SymbolType t)
return 4; return 4;
case SYMBOL_F32: case SYMBOL_F32:
return 4; return 4;
default: case SYMBOL_ARRAY:
break; 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; return 0;
} }
void 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) { if(sym->ref) {
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2\n", sym->ref); sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2\n", sym->ref);
StrBuf_append(a, out, uxn_temp_strbuf); StrBuf_append(a, out, uxn_temp_strbuf);
@ -812,15 +819,36 @@ uxn_emit_byte(Arena *a, List *out, const char *str, i32 length)
void void
uxn_emit_char(Arena *a, List *out, const char *str, i32 length) uxn_emit_char(Arena *a, List *out, const char *str, i32 length)
{ {
sprintf(uxn_temp_strbuf, "#%02x ", (char)str[1]); 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); StrBuf_append(a, out, uxn_temp_strbuf);
USED(length); USED(length);
} }
void 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) { if(sym->ref) {
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2\n", sym->ref); sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2\n", sym->ref);
StrBuf_append(a, out, uxn_temp_strbuf); StrBuf_append(a, out, uxn_temp_strbuf);
@ -1120,9 +1148,9 @@ uxn_emit_close_paren(Arena *a, List *out)
} }
void 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) { if(sym->ref) {
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2 ", sym->ref); sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2 ", sym->ref);
StrBuf_append(a, out, uxn_temp_strbuf); StrBuf_append(a, out, uxn_temp_strbuf);
@ -1137,9 +1165,9 @@ uxn_emit_variable(Arena *a, List *out, Symbol *sym, bool local)
} }
void 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) { if(sym->ref) {
sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2 ", sym->ref); sprintf(uxn_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2 ", sym->ref);
StrBuf_append(a, out, uxn_temp_strbuf); StrBuf_append(a, out, uxn_temp_strbuf);
@ -1417,8 +1445,18 @@ uxn_emit_halt(Arena *a, List *out)
void void
uxn_emit_deref_prolog(Arena *a, List *out, Symbol *sym) uxn_emit_deref_prolog(Arena *a, List *out, Symbol *sym)
{ {
sprintf(uxn_temp_strbuf, ";%.*s ", sym->name_length, sym->name); if(sym->scope) {
StrBuf_append(a, out, uxn_temp_strbuf); 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 void

View File

@ -319,9 +319,9 @@ identifierType(void)
if(lexer.current - lexer.start > 1) { if(lexer.current - lexer.start > 1) {
switch(lexer.start[1]) { switch(lexer.start[1]) {
case 'y': case 'y':
return check_keyword(2, 2, "te", TOKEN_TYPE_U8); return check_keyword(2, 2, "te", TOKEN_TYPE_BYTE);
case 'o': case 'o':
return check_keyword(2, 2, "ol", TOKEN_TYPE_U8); return check_keyword(2, 2, "ol", TOKEN_TYPE_BOOL);
} }
} }
break; break;

206
test/stdlib.ul Normal file
View File

@ -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 {
}

View File

@ -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 {
}

View File

@ -1,13 +1,22 @@
str hello = "hello World!\n"; str hello = "hello World!";
str msg = " damage inflicted!\n"; str msg = " damage inflicted!";
if (msg[1] == 'd') { if (msg[1] == 'd') {
print("yes\n"); pln("yes");
} }
print(msg.length as str); pln(msg.length as str);
print(msg); pln(msg);
hello[0] = hello[0] - ' '; hello[0] = hello[0] - ' ';
print(hello); pln(hello);
halt; halt;
function pln(str string) {
nat i = 0;
while (i < string.length) {
write = string[i];
i = i + 1;
}
write = '\n';
}