1
0
mirror of https://github.com/janet-lang/janet synced 2025-07-15 16:32:53 +00:00

Update assembly and add example.

This commit is contained in:
Calvin Rose 2018-03-16 14:34:48 -04:00
parent d3a1d97649
commit 72d8e74a71
4 changed files with 43 additions and 18 deletions

22
examples/assembly.dst Normal file
View File

@ -0,0 +1,22 @@
# Example of dst assembly
# Fibonacci sequence, implemented with naive recursion.
(def fibasm (asm '{
arity 1
bytecode [
(ldi 1 0x2) # $1 = 2
(lt 1 0 1) # $1 = $0 < $1
(jmpn 1 :recursive) # if (not $1) goto :recursive
(ret 0) # return $0
:recursive
(lds 1) # $1 = self
(addim 0 0 -0x1) # $0 = $0 - 1
(push 0) # push($0)
(call 2 1) # $2 = call($1)
(addim 0 0 -0x1) # $0 = $0 - 1
(push 0) # push($0)
(call 0 1) # $0 = call($1)
(addi 0 0 2) # $0 = $0 + $2 (integers)
(ret 0) # return $0
]
}))

View File

@ -56,6 +56,7 @@ struct DstAssembler {
DstFuncDef *def; DstFuncDef *def;
jmp_buf on_error; jmp_buf on_error;
const uint8_t *errmessage; const uint8_t *errmessage;
int32_t errindex;
int32_t environments_capacity; int32_t environments_capacity;
int32_t defs_capacity; int32_t defs_capacity;
@ -76,8 +77,8 @@ struct DstAssembler {
* prefix tree. */ * prefix tree. */
static const DstInstructionDef dst_ops[] = { static const DstInstructionDef dst_ops[] = {
{"add", DOP_ADD}, {"add", DOP_ADD},
{"addim", DOP_ADD_IMMEDIATE},
{"addi", DOP_ADD_INTEGER}, {"addi", DOP_ADD_INTEGER},
{"addim", DOP_ADD_IMMEDIATE},
{"addr", DOP_ADD_REAL}, {"addr", DOP_ADD_REAL},
{"band", DOP_BAND}, {"band", DOP_BAND},
{"bnot", DOP_BNOT}, {"bnot", DOP_BNOT},
@ -88,8 +89,8 @@ static const DstInstructionDef dst_ops[] = {
{"cmp", DOP_COMPARE}, {"cmp", DOP_COMPARE},
{"debug", DOP_DEBUG}, {"debug", DOP_DEBUG},
{"div", DOP_DIVIDE}, {"div", DOP_DIVIDE},
{"divim", DOP_DIVIDE_IMMEDIATE},
{"divi", DOP_DIVIDE_INTEGER}, {"divi", DOP_DIVIDE_INTEGER},
{"divim", DOP_DIVIDE_IMMEDIATE},
{"divr", DOP_DIVIDE_REAL}, {"divr", DOP_DIVIDE_REAL},
{"eq", DOP_EQUALS}, {"eq", DOP_EQUALS},
{"err", DOP_ERROR}, {"err", DOP_ERROR},
@ -99,25 +100,25 @@ static const DstInstructionDef dst_ops[] = {
{"jmp", DOP_JUMP}, {"jmp", DOP_JUMP},
{"jmpi", DOP_JUMP_IF}, {"jmpi", DOP_JUMP_IF},
{"jmpn", DOP_JUMP_IF_NOT}, {"jmpn", DOP_JUMP_IF_NOT},
{"ldc", DOP_LOAD_CONSTANT},
{"ldf", DOP_LOAD_FALSE},
{"ldi", DOP_LOAD_INTEGER},
{"ldn", DOP_LOAD_NIL},
{"lds", DOP_LOAD_SELF},
{"ldt", DOP_LOAD_TRUE},
{"ldu", DOP_LOAD_UPVALUE},
{"lt", DOP_LESS_THAN}, {"lt", DOP_LESS_THAN},
{"lc", DOP_LOAD_CONSTANT},
{"lf", DOP_LOAD_FALSE},
{"li", DOP_LOAD_INTEGER},
{"ln", DOP_LOAD_NIL},
{"ls", DOP_LOAD_SELF},
{"lt", DOP_LOAD_TRUE},
{"lu", DOP_LOAD_UPVALUE},
{"movf", DOP_MOVE_FAR}, {"movf", DOP_MOVE_FAR},
{"movn", DOP_MOVE_NEAR}, {"movn", DOP_MOVE_NEAR},
{"mul", DOP_MULTIPLY}, {"mul", DOP_MULTIPLY},
{"mulim", DOP_MULTIPLY_IMMEDIATE},
{"muli", DOP_MULTIPLY_INTEGER}, {"muli", DOP_MULTIPLY_INTEGER},
{"mulim", DOP_MULTIPLY_IMMEDIATE},
{"mulr", DOP_MULTIPLY_REAL}, {"mulr", DOP_MULTIPLY_REAL},
{"noop", DOP_NOOP}, {"noop", DOP_NOOP},
{"push", DOP_PUSH}, {"push", DOP_PUSH},
{"pusha", DOP_PUSH_ARRAY},
{"push2", DOP_PUSH_2}, {"push2", DOP_PUSH_2},
{"push3", DOP_PUSH_3}, {"push3", DOP_PUSH_3},
{"pusha", DOP_PUSH_ARRAY},
{"put", DOP_PUT}, {"put", DOP_PUT},
{"puti", DOP_PUT_INDEX}, {"puti", DOP_PUT_INDEX},
{"res", DOP_RESUME}, {"res", DOP_RESUME},
@ -168,7 +169,7 @@ static void dst_asm_deinit(DstAssembler *a) {
/* Throw some kind of assembly error */ /* Throw some kind of assembly error */
static void dst_asm_error(DstAssembler *a, const char *message) { static void dst_asm_error(DstAssembler *a, const char *message) {
a->errmessage = dst_cstring(message); a->errmessage = dst_formatc("%s, instruction %d", message, a->errindex);
longjmp(a->on_error, 1); longjmp(a->on_error, 1);
} }
#define dst_asm_assert(a, c, m) do { if (!(c)) dst_asm_error((a), (m)); } while (0) #define dst_asm_assert(a, c, m) do { if (!(c)) dst_asm_error((a), (m)); } while (0)
@ -469,6 +470,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
a.def = def; a.def = def;
a.parent = parent; a.parent = parent;
a.errmessage = NULL; a.errmessage = NULL;
a.errindex = 0;
a.environments_capacity = 0; a.environments_capacity = 0;
a.bytecode_count = 0; a.bytecode_count = 0;
a.defs_capacity = 0; a.defs_capacity = 0;
@ -613,6 +615,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
} else if (dst_checktype(instr, DST_TUPLE)) { } else if (dst_checktype(instr, DST_TUPLE)) {
blength++; blength++;
} else { } else {
a.errindex = i;
dst_asm_error(&a, "expected assembly instruction"); dst_asm_error(&a, "expected assembly instruction");
} }
} }
@ -631,6 +634,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
uint32_t op; uint32_t op;
const DstInstructionDef *idef; const DstInstructionDef *idef;
const Dst *t; const Dst *t;
a.errindex = i;
dst_asm_assert(&a, dst_checktype(instr, DST_TUPLE), "expected tuple"); dst_asm_assert(&a, dst_checktype(instr, DST_TUPLE), "expected tuple");
t = dst_unwrap_tuple(instr); t = dst_unwrap_tuple(instr);
if (dst_tuple_length(t) == 0) { if (dst_tuple_length(t) == 0) {
@ -653,6 +657,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
} else { } else {
dst_asm_error(&a, "bytecode expected"); dst_asm_error(&a, "bytecode expected");
} }
a.errindex = -1;
/* Check for source mapping */ /* Check for source mapping */
x = dst_get(s, dst_csymbolv("sourcemap")); x = dst_get(s, dst_csymbolv("sourcemap"));

View File

@ -335,15 +335,13 @@ If no match is found, returns nil"
(foreach s (fn [x] (put tab x true))) (foreach s (fn [x] (put tab x true)))
(keys tab)) (keys tab))
(defn make-env [parent] (defn make-env [parent safe]
(def parent (if parent parent _env)) (def parent (if parent parent _env))
(def newenv (setproto @{} parent)) (def newenv (setproto @{} parent))
(put newenv '_env @{'value newenv}) (if (not safe)
(put newenv '_env @{'value newenv}))
newenv) newenv)
# Remove the reference to the default _env
(put _env '_env nil)
(def run-context (def run-context
"Run a context. This evaluates expressions of dst in an environment, "Run a context. This evaluates expressions of dst in an environment,
and is encapsulates the parsing, compilation, and evaluation of dst. and is encapsulates the parsing, compilation, and evaluation of dst.

View File

@ -28,7 +28,7 @@
(dohandler (string-slice arg 1 2)) (dohandler (string-slice arg 1 2))
(do (do
(varset! no-file false) (varset! no-file false)
(require arg)))) (import arg))))
(when (or should-repl no-file) (when (or should-repl no-file)
(print (string "Dst " VERSION " Copyright (C) 2017-2018 Calvin Rose")) (print (string "Dst " VERSION " Copyright (C) 2017-2018 Calvin Rose"))