all repos — hex @ 0508b1bcaab2c9f6df300c600ab1bcba283600e5

A tiny, minimalist, slightly-esoteric concatenative programming lannguage.

Enhanced ! to be able to evaluate bytecode.
h3rald h3rald@h3rald.com
Thu, 19 Dec 2024 15:53:53 +0100
commit

0508b1bcaab2c9f6df300c600ab1bcba283600e5

parent

12ed6beae51879853bf6db70452567f197eb9874

M CHANGELOG.mdCHANGELOG.md

@@ -6,6 +6,7 @@ <h4>New Features</h4>

<ul> <li>Implemented a virtual machine with a bytecode compiler and interpreter.</li> <li>{{sym-read}}, {{sym-write}}, {{sym-append}} now support reading and writing from/to binary files as well.</li> + <li>{{sym-!}} can now evaluate a quotation of integers as hex bytecode.</li> </ul> <h4>Fixes</h4>
M releases/0.2.0.htmlreleases/0.2.0.html

@@ -4,6 +4,7 @@ <h4>New Features</h4>

<ul> <li>Implemented a virtual machine with a bytecode compiler and interpreter.</li> <li>{{sym-read}}, {{sym-write}}, {{sym-append}} now support reading and writing from/to binary files as well.</li> + <li>{{sym-!}} can now evaluate a quotation of integers as hex bytecode.</li> </ul> <h4>Fixes</h4>
M scripts/test.hexscripts/test.hex

@@ -148,7 +148,7 @@ ((0x2 #) (error) try "Symbol name must be a string" ==)

;72 (("puts" .) (error) try "Symbol '.' requires a quotation" ==) - (((puts) !) (error) try "Symbol '!' requires a string" ==) + (((puts) !) (error) try "Quotation must contain only integers" ==) (("3" 0x3 +) (error) try "Symbol '+' requires two integers" ==) (("3" 0x3 -) (error) try "Symbol '-' requires two integers" ==) ;76
M scripts/web.hexscripts/web.hex

@@ -16,8 +16,8 @@ d-releases ls . "releases" :

d-templates "/page.html" cat "t-page" : ; Symbols to substitute with the corresponding links -("split" "run" "get" "puts" ":" "." "#" "==" "'" "swap" -"+" "*" "-" "each" "cat" "print" "read" "dec" "write" "append") "symbol-links" : +("split" "run" "get" "puts" ":" "." "#" "==" "'" "swap" "dup" +"+" "*" "-" "each" "cat" "print" "read" "dec" "write" "append" "!") "symbol-links" : ;; Syntax highlighting
M src/doc.csrc/doc.c

@@ -49,7 +49,7 @@ hex_doc(docs, "clear", "", "", "Clears the stack.");

// Evaluation hex_doc(docs, ".", "q", "*", "Pushes each item of 'q' on the stack."); - hex_doc(docs, "!", "s", "", "Evaluates 's' as a hex program."); + hex_doc(docs, "!", "(s|q)", "*", "Evaluates 's' as a hex program or 'q' as hex bytecode."); hex_doc(docs, "'", "a", "q", "Wraps 'a' in a quotation."); // Arithmetic
M src/symbols.csrc/symbols.c

@@ -121,23 +121,58 @@ }

return 0; } -// evaluate a string +// evaluate a string or bytecode array int hex_symbol_eval(hex_context_t *ctx) { - HEX_POP(ctx, item); if (item.type == HEX_TYPE_INVALID) { HEX_FREE(ctx, item); return 1; } - if (item.type != HEX_TYPE_STRING) + if (item.type == HEX_TYPE_STRING) + { + return hex_interpret(ctx, item.data.str_value, "<!>", 1, 1); + } + else if (item.type == HEX_TYPE_QUOTATION) + { + for (size_t i = 0; i < item.quotation_size; i++) + { + if (item.data.quotation_value[i]->type != HEX_TYPE_INTEGER) + { + hex_error(ctx, "Quotation must contain only integers"); + HEX_FREE(ctx, item); + return 1; + } + } + uint8_t *bytecode = (uint8_t *)malloc(item.quotation_size * sizeof(uint8_t)); + if (!bytecode) + { + hex_error(ctx, "Memory allocation failed"); + HEX_FREE(ctx, item); + return 1; + } + for (size_t i = 0; i < item.quotation_size; i++) + { + if (item.data.quotation_value[i]->type != HEX_TYPE_INTEGER) + { + hex_error(ctx, "Quotation must contain only integers"); + free(bytecode); + HEX_FREE(ctx, item); + return 1; + } + bytecode[i] = (uint8_t)item.data.quotation_value[i]->data.int_value; + } + int result = hex_interpret_bytecode(ctx, bytecode, item.quotation_size); + free(bytecode); + return result; + } + else { - hex_error(ctx, "Symbol '!' requires a string"); + hex_error(ctx, "Symbol '!' requires a string or a quotation of integers"); HEX_FREE(ctx, item); return 1; } - return hex_interpret(ctx, item.data.str_value, "<!>", 1, 1); } // IO Symbols
M web/contents/spec.htmlweb/contents/spec.html

@@ -381,8 +381,9 @@ <h5 id="i-symbol"><code>$:.$$</code> Symbol<a href="#top"></a></h5>

<p><mark>q &rarr; *</mark></p> <p>Dequotes quotation <code>q</code>.</p> <h5 id="eval-symbol"><code>$:!$$</code> Symbol<a href="#top"></a></h5> - <p><mark>s &rarr;</mark></p> - <p>Evaluates the string <code>s</code> as an hex program.</p> + <p><mark>(s|q) &rarr; *</mark></p> + <p>Evaluates the string <code>s</code> as an hex program, or the array of integers to be interpreted as hex bytecode + (HBX format).</p> <h5 id="quote-symbol"><code>$:&#39;$$</code> Symbol<a href="#top"></a></h5> <p><mark>a &rarr; q</mark></p> <p>Pushes the literal <code>a</code> wrapped in a quotation on the stack.</p>