From b1e1160bff5708397bad363f73a4e33dbe1749dc Mon Sep 17 00:00:00 2001 From: hanez Date: Wed, 10 Dec 2025 00:30:24 +0100 Subject: [PATCH] Added echo to output data wthout a newline. (0.36.2) --- CMakeLists.txt | 2 +- src/bytecode.c | 1 + src/bytecode.h | 1 + src/parser.c | 30 ++++++++++++++++++++++++++++++ src/vm.c | 1 + src/vm.h | 2 +- 6 files changed, 35 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bc6100..f8323b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(fun VERSION 0.36.1 LANGUAGES C) +project(fun VERSION 0.36.2 LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/src/bytecode.c b/src/bytecode.c index 2dd3517..647c365 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -77,6 +77,7 @@ static const char *opcode_name(OpCode op) { case OP_CALL: return "CALL"; case OP_RETURN: return "RETURN"; case OP_PRINT: return "PRINT"; + case OP_ECHO: return "ECHO"; case OP_HALT: return "HALT"; case OP_MOD: return "MOD"; case OP_AND: return "AND"; diff --git a/src/bytecode.h b/src/bytecode.h index 0576cfb..dc9563b 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -43,6 +43,7 @@ typedef enum { OP_RETURN, // pop optional return value and return to caller OP_PRINT, + OP_ECHO, // like print but does not append a newline; prints immediately OP_HALT, OP_LINE, // operand = source line number (debug marker) diff --git a/src/parser.c b/src/parser.c index 00074a1..b61d5fd 100644 --- a/src/parser.c +++ b/src/parser.c @@ -2806,6 +2806,21 @@ static void parse_simple_statement(Bytecode *bc, const char *src, size_t len, si return; } + if (strcmp(name, "echo") == 0) { + free(name); + skip_spaces(src, len, &local_pos); + (void)consume_char(src, len, &local_pos, '('); + if (emit_expression(bc, src, len, &local_pos)) { + (void)consume_char(src, len, &local_pos, ')'); + bytecode_add_instruction(bc, OP_ECHO, 0); + } else { + (void)consume_char(src, len, &local_pos, ')'); + } + *pos = local_pos; + skip_to_eol(src, len, pos); + return; + } + /* assignment or simple call */ int lidx = local_find(name); int gi = (lidx < 0) ? sym_index(name) : -1; @@ -3120,6 +3135,21 @@ static void parse_simple_statement(Bytecode *bc, const char *src, size_t len, si return; } + /* echo(expr): like print but does not add a newline (immediate output) */ + if (starts_with(src, len, *pos, "echo")) { + *pos += 4; + skip_spaces(src, len, pos); + (void)consume_char(src, len, pos, '('); + if (emit_expression(bc, src, len, pos)) { + (void)consume_char(src, len, pos, ')'); + bytecode_add_instruction(bc, OP_ECHO, 0); + } else { + (void)consume_char(src, len, pos, ')'); + } + skip_to_eol(src, len, pos); + return; + } + /* unknown token: report error */ parser_fail(*pos, "Unknown token at start of statement"); } diff --git a/src/vm.c b/src/vm.c index 9beaabe..18fb613 100644 --- a/src/vm.c +++ b/src/vm.c @@ -794,6 +794,7 @@ void vm_run(VM *vm, Bytecode *entry) { #include "vm/len.c" #include "vm/line.c" #include "vm/print.c" + #include "vm/echo.c" #include "vm/to_number.c" #include "vm/to_string.c" #include "vm/cast.c" diff --git a/src/vm.h b/src/vm.h index dd9e756..5b603e5 100644 --- a/src/vm.h +++ b/src/vm.h @@ -22,7 +22,7 @@ static const char *opcode_names[] = { "NOP","LOAD_CONST","LOAD_LOCAL","STORE_LOCAL", "LOAD_GLOBAL","STORE_GLOBAL","ADD","SUB","MUL","DIV", "LT","LTE","GT","GTE","EQ","NEQ","POP","JUMP", - "JUMP_IF_FALSE","CALL","RETURN","PRINT","HALT", + "JUMP_IF_FALSE","CALL","RETURN","PRINT","ECHO","HALT", "LINE", "MOD","AND","OR","NOT","DUP","SWAP", "MAKE_ARRAY","INDEX_GET","INDEX_SET",