diff --git a/src/arch/linux-sdl/main.c b/src/arch/linux-sdl/main.c new file mode 100644 index 0000000..e818591 --- /dev/null +++ b/src/arch/linux-sdl/main.c @@ -0,0 +1,157 @@ +#include "../../compiler.h" +#include "../../vm.h" +#include + +#define MAX_SRC_SIZE 16384 + +void compileFile(const char *path, VM *vm) { + FILE *f = fopen(path, "rb"); + if (!f) { + perror("fopen"); + exit(1); + } + + static char source[MAX_SRC_SIZE + 1]; + + fseek(f, 0, SEEK_END); + long len = ftell(f); + fseek(f, 0, SEEK_SET); + if (len >= MAX_SRC_SIZE) { + perror("source is larget than buffer"); + exit(1); + } + size_t read = fread(source, 1, len, f); + source[read] = '\0'; + fclose(f); + + compile(source, vm); +} + +static void repl(VM *vm) { + char line[1024]; + for (;;) { + printf("> "); + + if (!fgets(line, sizeof(line), stdin)) { + printf("\n"); + break; + } + /* reset the code counter to 0 */ + vm->cp = 0; + vm->sp = 0; + vm->pc = 0; + vm->mp = 0; + + compile(line, vm); + while (step_vm(vm)); + } + exit(0); +} + +int main(int argc, char **argv) { + VM vm = {0}; + vm.frames_size = FRAMES_SIZE; + vm.return_stack_size = STACK_SIZE; + vm.stack_size = STACK_SIZE; + vm.memory_size = MEMORY_SIZE; + + if (argc == 1) { + repl(&vm); + } else if (argc == 2) { + compileFile(argv[1], &vm); + } else { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 64; + } + + uint32_t buffer_size = 640 * 480 * sizeof(uint32_t); + + Device screen; + screen.type = SCREEN; + screen.s = (Screen){.width = (uint8_t)480, + .height = (uint8_t)640, + .allocated = {vm.mp, buffer_size}, + .buffer = &vm.memory[vm.mp]}; + vm.devices[vm.dp++] = screen; + vm.mp += buffer_size; + + Device mouse; + mouse.type = MOUSE; + mouse.m = (Mouse){.x = 0, .y = 0, .btn1 = 0, .btn2 = 0, .btn3 = 0}; + vm.devices[vm.dp++] = mouse; + + Device keyboard; + keyboard.type = KEYBOARD; + const uint8_t *state = SDL_GetKeyboardState(NULL); + keyboard.k = (Keyboard){.length = SDL_NUM_SCANCODES, .keys = state}; + vm.devices[vm.dp++] = keyboard; + + /* Create window and renderer */ + SDL_Window *window = + SDL_CreateWindow("Reality Engine VM", SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, screen.s.width, screen.s.height, + SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); + + SDL_Renderer *renderer = SDL_CreateRenderer( + window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + + /* Create texture for 640x480 buffer */ + SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + screen.s.width, screen.s.height); + + /* Enable nearest-neighbor scaling (preserves pixel art) */ + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); /* "0" = nearest-neighbor */ + + bool running = true; + while (running) { + step_vm(&vm); + SDL_PumpEvents(); + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + running = false; + break; + case SDL_MOUSEBUTTONDOWN: + printf("mouse_down: x=%d, y=%d, btn=%d\n", event.button.x, + event.button.y, event.button.button); + break; + case SDL_MOUSEMOTION: + printf("mouse_move: x=%d, y=%d\n", event.motion.x, event.motion.y); + break; + case SDL_FINGERDOWN: + printf("touch_down x=%d, y=%d\n", + (int)(event.tfinger.x * screen.s.width), + (int)(event.tfinger.y * screen.s.height)); + break; + case SDL_FINGERMOTION: + printf("touch_move x=%d, y=%d\n", + (int)(event.tfinger.x * screen.s.width), + (int)(event.tfinger.y * screen.s.height)); + break; + } + } + + SDL_UpdateTexture(texture, NULL, screen.s.buffer, + screen.s.width * sizeof(uint32_t)); + + SDL_RenderClear(renderer); + + /* (Scales to fit screen while preserving pixel grid) */ + SDL_Rect output_rect; + SDL_RenderGetViewport(renderer, &output_rect); + float scale_x = (float)output_rect.w / screen.s.width; + float scale_y = (float)output_rect.h / screen.s.height; + float scale = SDL_min(scale_x, scale_y); + + SDL_Rect dstrect = {(int)((output_rect.w - screen.s.width * scale) / 2), + (int)((output_rect.h - screen.s.height * scale) / 2), + (int)(screen.s.width * scale), + (int)(screen.s.height * scale)}; + + SDL_RenderCopy(renderer, texture, NULL, &dstrect); + SDL_RenderPresent(renderer); + } + return 0; +} diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c index e818591..def5a7d 100644 --- a/src/arch/linux/main.c +++ b/src/arch/linux/main.c @@ -1,6 +1,5 @@ #include "../../compiler.h" #include "../../vm.h" -#include #define MAX_SRC_SIZE 16384 @@ -64,94 +63,9 @@ int main(int argc, char **argv) { return 64; } - uint32_t buffer_size = 640 * 480 * sizeof(uint32_t); - - Device screen; - screen.type = SCREEN; - screen.s = (Screen){.width = (uint8_t)480, - .height = (uint8_t)640, - .allocated = {vm.mp, buffer_size}, - .buffer = &vm.memory[vm.mp]}; - vm.devices[vm.dp++] = screen; - vm.mp += buffer_size; - - Device mouse; - mouse.type = MOUSE; - mouse.m = (Mouse){.x = 0, .y = 0, .btn1 = 0, .btn2 = 0, .btn3 = 0}; - vm.devices[vm.dp++] = mouse; - - Device keyboard; - keyboard.type = KEYBOARD; - const uint8_t *state = SDL_GetKeyboardState(NULL); - keyboard.k = (Keyboard){.length = SDL_NUM_SCANCODES, .keys = state}; - vm.devices[vm.dp++] = keyboard; - - /* Create window and renderer */ - SDL_Window *window = - SDL_CreateWindow("Reality Engine VM", SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, screen.s.width, screen.s.height, - SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); - - SDL_Renderer *renderer = SDL_CreateRenderer( - window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); - - /* Create texture for 640x480 buffer */ - SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, - screen.s.width, screen.s.height); - - /* Enable nearest-neighbor scaling (preserves pixel art) */ - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); /* "0" = nearest-neighbor */ - bool running = true; while (running) { - step_vm(&vm); - SDL_PumpEvents(); - SDL_Event event; - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - running = false; - break; - case SDL_MOUSEBUTTONDOWN: - printf("mouse_down: x=%d, y=%d, btn=%d\n", event.button.x, - event.button.y, event.button.button); - break; - case SDL_MOUSEMOTION: - printf("mouse_move: x=%d, y=%d\n", event.motion.x, event.motion.y); - break; - case SDL_FINGERDOWN: - printf("touch_down x=%d, y=%d\n", - (int)(event.tfinger.x * screen.s.width), - (int)(event.tfinger.y * screen.s.height)); - break; - case SDL_FINGERMOTION: - printf("touch_move x=%d, y=%d\n", - (int)(event.tfinger.x * screen.s.width), - (int)(event.tfinger.y * screen.s.height)); - break; - } - } - - SDL_UpdateTexture(texture, NULL, screen.s.buffer, - screen.s.width * sizeof(uint32_t)); - - SDL_RenderClear(renderer); - - /* (Scales to fit screen while preserving pixel grid) */ - SDL_Rect output_rect; - SDL_RenderGetViewport(renderer, &output_rect); - float scale_x = (float)output_rect.w / screen.s.width; - float scale_y = (float)output_rect.h / screen.s.height; - float scale = SDL_min(scale_x, scale_y); - - SDL_Rect dstrect = {(int)((output_rect.w - screen.s.width * scale) / 2), - (int)((output_rect.h - screen.s.height * scale) / 2), - (int)(screen.s.width * scale), - (int)(screen.s.height * scale)}; - - SDL_RenderCopy(renderer, texture, NULL, &dstrect); - SDL_RenderPresent(renderer); + running = step_vm(&vm); } return 0; } diff --git a/src/compiler.c b/src/compiler.c index 4d65e03..7393255 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -51,9 +51,7 @@ void errorAt(Token *token, const char *message) { void error(const char *message) { errorAt(&parser.previous, message); } -void errorAtCurrent(const char *message) { - errorAt(&parser.current, message); -} +void errorAtCurrent(const char *message) { errorAt(&parser.current, message); } void advance() { parser.previous = parser.current; @@ -76,20 +74,16 @@ void consume(TokenType type, const char *message) { errorAtCurrent(message); } - -static bool check(TokenType type) { - return parser.current.type == type; -} +static bool check(TokenType type) { return parser.current.type == type; } static bool match(TokenType type) { - if (!check(type)) return false; + if (!check(type)) + return false; advance(); return true; } - -void emitOp(VM *vm, uint8_t opcode, uint8_t dest, uint8_t src1, - uint8_t src2) { +void emitOp(VM *vm, uint8_t opcode, uint8_t dest, uint8_t src1, uint8_t src2) { vm->code[vm->cp++].u = OP(opcode, dest, src1, src2); } @@ -155,22 +149,23 @@ void unary(VM *vm) { static void literal(VM *vm) { switch (parser.previous.type) { - case TOKEN_KEYWORD_NIL: { - emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); - vm->code[vm->cp++].u = 0; - break; - } - case TOKEN_KEYWORD_FALSE: { - emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); - vm->code[vm->cp++].u = 0; - break; - } - case TOKEN_KEYWORD_TRUE: { - emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); - vm->code[vm->cp++].u = 1; - break; - } - default: return; + case TOKEN_KEYWORD_NIL: { + emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); + vm->code[vm->cp++].u = 0; + break; + } + case TOKEN_KEYWORD_FALSE: { + emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); + vm->code[vm->cp++].u = 0; + break; + } + case TOKEN_KEYWORD_TRUE: { + emitOp(vm, OP_LOADU, vm->frames[vm->fp].rp++, 0, 0); + vm->code[vm->cp++].u = 1; + break; + } + default: + return; } } @@ -180,25 +175,18 @@ void binary(VM *vm) { parsePrecedence(vm, (Precedence)(rule->precedence + 1)); TokenType operandType = parser.previous.type; + Frame f = vm->frames[vm->fp]; + uint32_t src1 = f.rp--; + uint32_t src2 = f.rp--; + uint32_t dest = f.rp++; + switch (operatorType) { case TOKEN_PLUS: if (operandType == TOKEN_UINT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_ADD_UINT, dest, src1, src2); } else if (operandType == TOKEN_INT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_ADD_INT, dest, src1, src2); } else if (operandType == TOKEN_FLOAT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_ADD_REAL, dest, src1, src2); } else { error("not numeric"); @@ -206,22 +194,10 @@ void binary(VM *vm) { break; case TOKEN_MINUS: if (operandType == TOKEN_UINT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_SUB_UINT, dest, src1, src2); } else if (operandType == TOKEN_INT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_SUB_INT, dest, src1, src2); } else if (operandType == TOKEN_FLOAT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_SUB_REAL, dest, src1, src2); } else { error("not numeric"); @@ -229,22 +205,10 @@ void binary(VM *vm) { break; case TOKEN_STAR: if (operandType == TOKEN_UINT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_MUL_UINT, dest, src1, src2); } else if (operandType == TOKEN_INT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_MUL_INT, dest, src1, src2); } else if (operandType == TOKEN_FLOAT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_MUL_REAL, dest, src1, src2); } else { error("not numeric"); @@ -252,22 +216,10 @@ void binary(VM *vm) { break; case TOKEN_SLASH: if (operandType == TOKEN_UINT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_DIV_UINT, dest, src1, src2); } else if (operandType == TOKEN_INT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_DIV_INT, dest, src1, src2); } else if (operandType == TOKEN_FLOAT_LITERAL) { - Frame f = vm->frames[vm->fp]; - uint32_t src1 = f.rp--; - uint32_t src2 = f.rp--; - uint32_t dest = f.rp++; emitOp(vm, OP_DIV_REAL, dest, src1, src2); } else { error("not numeric"); @@ -347,7 +299,7 @@ void printStatement(VM *vm) { expression(vm); consume(TOKEN_SEMICOLON, "Expect ';' after value."); Frame f = vm->frames[vm->fp]; - vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, f.rp--, 0); + vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, f.rp--, 0); } static void expressionStatement(VM *vm) { @@ -355,18 +307,29 @@ static void expressionStatement(VM *vm) { consume(TOKEN_SEMICOLON, "Expect ';' after expression."); } +static void intDeclaration(VM *vm) { + /* insert variable name in symbol table */ + + if (match(TOKEN_EQ)) { + expression(vm); + } else { + /* not sure here yet */ + } + + consume(TOKEN_SEMICOLON, "Expect ';' after expression."); +} + void statement(VM *vm) { if (match(TOKEN_KEYWORD_PRINT)) { printStatement(vm); + } else if (match(TOKEN_TYPE_INT)) { + intDeclaration(vm); } else { expressionStatement(vm); } } -void declaration(VM *vm) { - statement(vm); -} - +void declaration(VM *vm) { statement(vm); } bool compile(const char *source, VM *vm) { initLexer(source); diff --git a/src/compiler.h b/src/compiler.h index 198a357..8db35ec 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -4,6 +4,15 @@ #include "lexer.h" #include "opcodes.h" +typedef struct symbol_table_t { + char name[32]; + +} Symbol; + +typedef struct module_t { + char name[32]; + Symbol list[256]; +} Module; bool compile(const char* source, VM* vm); diff --git a/src/opcodes.h b/src/opcodes.h index 63f7523..157f4b2 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -37,7 +37,7 @@ typedef struct mouse_t { uint8_t btn3; } Mouse; -typedef struct keyboard_t { +typedef struct keyboard_t { uint32_t length; const uint8_t *keys; } Keyboard; @@ -51,7 +51,7 @@ typedef union device_u { #define MEMORY_SIZE 65536 #define CODE_SIZE 8192 -#define FRAMES_SIZE 128 +#define FRAMES_SIZE 128 #define STACK_SIZE 256 #define DEVICES_SIZE 8 typedef struct vm_s { @@ -77,21 +77,21 @@ typedef struct vm_s { } VM; typedef enum { - OP_HALT, /* halt : terminate execution */ - OP_LOADI, /* lodi : dest = next memory location as int */ - OP_LOADU, /* lodu : dest = next memory location as uint */ - OP_LOADF, /* lodf : dest = next memory location as float */ - OP_STOREI, /* stri : next memory location = src1 as int */ - OP_STOREU, /* stru : next memory location = src1 as uint */ - OP_STOREF, /* strf : next memory location = src1 as float */ - OP_PUSHI, /* pshi : push int from register onto the stack */ - OP_PUSHU, /* pshu : push uint from register onto the stack */ - OP_PUSHF, /* pshf : push float from register onto the stack */ - OP_PUSHS, /* pshs : push str ref from register onto the stack and copy str */ - OP_POPI, /* popi : pop int from stack onto the register */ - OP_POPU, /* popu : pop uint from stack onto the register */ - OP_POPF, /* popf : pop float from stack onto the register */ - OP_POPS, /* pops : pop str ref from stack and move/copy to register */ + OP_HALT, /* halt : terminate execution */ + OP_LOADI, /* lodi : dest = next memory location as int */ + OP_LOADU, /* lodu : dest = next memory location as uint */ + OP_LOADF, /* lodf : dest = next memory location as float */ + OP_STOREI, /* stri : next memory location = src1 as int */ + OP_STOREU, /* stru : next memory location = src1 as uint */ + OP_STOREF, /* strf : next memory location = src1 as float */ + OP_PUSHI, /* pshi : push int from register onto the stack */ + OP_PUSHU, /* pshu : push uint from register onto the stack */ + OP_PUSHF, /* pshf : push float from register onto the stack */ + OP_PUSHS, /* pshs : push str ref from register onto the stack and copy str */ + OP_POPI, /* popi : pop int from stack onto the register */ + OP_POPU, /* popu : pop uint from stack onto the register */ + OP_POPF, /* popf : pop float from stack onto the register */ + OP_POPS, /* pops : pop str ref from stack and move/copy to register */ OP_ADD_INT, /* addi : dest = src1 + src2 */ OP_SUB_INT, /* subi : dest = src1 - src2 */ OP_MUL_INT, /* muli : dest = src1 * src2 */ @@ -123,7 +123,8 @@ typedef enum { OP_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */ OP_REAL_TO_INT, /* rtoi : dest = src1 as int */ OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */ - OP_MOV, /* move : dest = src1 */ + OP_REG_MOV, /* rmov : dest = src1 */ + OP_REG_SWAP, /* rswp : dest = src1, src1 = dest */ OP_JMP, /* jump : jump to address src1 unconditionally */ OP_CALL, /* call : creates a new frame */ OP_RETURN, /* retn : returns from a frame to the parent frame */ @@ -134,6 +135,10 @@ typedef enum { OP_PRINT_STRING, /* puts : write src1 to stdout */ OP_CMP_STRING, /* cmps : dest = (str == src2) as bool */ OP_NOT, + OP_MEM_SWAP, + OP_MEM_MOV, + OP_NEW_ARRAY, + OP_NEW_PLEX, } Opcode; typedef enum { diff --git a/src/vm.c b/src/vm.c index 2c489a4..0ad4f82 100644 --- a/src/vm.c +++ b/src/vm.c @@ -150,8 +150,16 @@ bool step_vm(VM *vm) { vm->frames[vm->fp].registers[dest].f = (float)(vm->frames[vm->fp].registers[src1].u); return true; - case OP_MOV: - vm->frames[vm->fp].registers[dest] = vm->frames[vm->fp].registers[src1]; + case OP_REG_SWAP: + vm->frames[vm->fp].registers[dest].u ^= + vm->frames[vm->fp].registers[src1].u; + vm->frames[vm->fp].registers[src1].u ^= + vm->frames[vm->fp].registers[dest].u; + vm->frames[vm->fp].registers[dest].u ^= + vm->frames[vm->fp].registers[src1].u; + return true; + case OP_REG_MOV: + vm->frames[vm->fp].registers[dest].i = vm->code[vm->pc++].i; return true; case OP_JMP: vm->pc = vm->frames[vm->fp].registers[dest].u; /* Jump to address */ @@ -288,6 +296,42 @@ bool step_vm(VM *vm) { vm->memory[dest].u = equal; return true; } + case OP_NEW_ARRAY: { + uint32_t arr_dest = (uint32_t)vm->frames[vm->fp] + .allocated.end; /* get start of unallocated */ + vm->frames[vm->fp].registers[dest].u = + arr_dest; /* store ptr of array to dest register */ + uint32_t length = vm->code[vm->pc++].u; + if (src1) { /* if has inline data */ + uint32_t i = 0; + for (i = 0; i < length; i++) { + vm->memory[arr_dest + i] = vm->code[vm->pc++]; + } + } + vm->memory[arr_dest].u = length; + vm->frames[vm->fp].allocated.end += + length; /* increment to end of allocated */ + return true; + } + case OP_NEW_PLEX: { + uint32_t plex_dest = (uint32_t)vm->frames[vm->fp] + .allocated.end; /* get start of unallocated */ + vm->frames[vm->fp].registers[dest].u = + plex_dest; /* store ptr of array to dest register */ + uint32_t length = vm->code[vm->pc++].u; + vm->memory[plex_dest].u = length; + vm->frames[vm->fp].allocated.end += + length; /* increment to end of allocated */ + return true; + } + case OP_MEM_MOV: + vm->memory[dest] = vm->memory[src1]; + return true; + case OP_MEM_SWAP: + vm->memory[dest].u ^= vm->memory[src1].u; + vm->memory[src1].u ^= vm->memory[dest].u; + vm->memory[dest].u ^= vm->memory[src1].u; + return true; } return false; /* something bad happened */ } diff --git a/test/add.zrl b/test/add.zrl index aa7b913..fb2e0f1 100644 --- a/test/add.zrl +++ b/test/add.zrl @@ -3,4 +3,4 @@ fn add(int a, int b) int { } int sum = add(1, 1); -print(sum.toS()); +print(sum.str); diff --git a/test/hello.zrl b/test/hello.zrl index f4b3d3a..dd150bd 100644 --- a/test/hello.zrl +++ b/test/hello.zrl @@ -1 +1 @@ -print("nuqheH 'u'?"); +print("nuqneH 'u'?"); diff --git a/test/simple.zrl b/test/simple.zrl index 9b3c2e2..2d493c5 100644 --- a/test/simple.zrl +++ b/test/simple.zrl @@ -1,2 +1,2 @@ int sum = 1 + 2; -print(sum.toS()); +print(sum.str);