mirror of
https://github.com/janet-lang/janet
synced 2024-11-24 17:27:18 +00:00
Update assembly and add example.
This commit is contained in:
parent
d3a1d97649
commit
72d8e74a71
22
examples/assembly.dst
Normal file
22
examples/assembly.dst
Normal 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
|
||||
]
|
||||
}))
|
@ -56,6 +56,7 @@ struct DstAssembler {
|
||||
DstFuncDef *def;
|
||||
jmp_buf on_error;
|
||||
const uint8_t *errmessage;
|
||||
int32_t errindex;
|
||||
|
||||
int32_t environments_capacity;
|
||||
int32_t defs_capacity;
|
||||
@ -76,8 +77,8 @@ struct DstAssembler {
|
||||
* prefix tree. */
|
||||
static const DstInstructionDef dst_ops[] = {
|
||||
{"add", DOP_ADD},
|
||||
{"addim", DOP_ADD_IMMEDIATE},
|
||||
{"addi", DOP_ADD_INTEGER},
|
||||
{"addim", DOP_ADD_IMMEDIATE},
|
||||
{"addr", DOP_ADD_REAL},
|
||||
{"band", DOP_BAND},
|
||||
{"bnot", DOP_BNOT},
|
||||
@ -88,8 +89,8 @@ static const DstInstructionDef dst_ops[] = {
|
||||
{"cmp", DOP_COMPARE},
|
||||
{"debug", DOP_DEBUG},
|
||||
{"div", DOP_DIVIDE},
|
||||
{"divim", DOP_DIVIDE_IMMEDIATE},
|
||||
{"divi", DOP_DIVIDE_INTEGER},
|
||||
{"divim", DOP_DIVIDE_IMMEDIATE},
|
||||
{"divr", DOP_DIVIDE_REAL},
|
||||
{"eq", DOP_EQUALS},
|
||||
{"err", DOP_ERROR},
|
||||
@ -99,25 +100,25 @@ static const DstInstructionDef dst_ops[] = {
|
||||
{"jmp", DOP_JUMP},
|
||||
{"jmpi", DOP_JUMP_IF},
|
||||
{"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},
|
||||
{"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},
|
||||
{"movn", DOP_MOVE_NEAR},
|
||||
{"mul", DOP_MULTIPLY},
|
||||
{"mulim", DOP_MULTIPLY_IMMEDIATE},
|
||||
{"muli", DOP_MULTIPLY_INTEGER},
|
||||
{"mulim", DOP_MULTIPLY_IMMEDIATE},
|
||||
{"mulr", DOP_MULTIPLY_REAL},
|
||||
{"noop", DOP_NOOP},
|
||||
{"push", DOP_PUSH},
|
||||
{"pusha", DOP_PUSH_ARRAY},
|
||||
{"push2", DOP_PUSH_2},
|
||||
{"push3", DOP_PUSH_3},
|
||||
{"pusha", DOP_PUSH_ARRAY},
|
||||
{"put", DOP_PUT},
|
||||
{"puti", DOP_PUT_INDEX},
|
||||
{"res", DOP_RESUME},
|
||||
@ -168,7 +169,7 @@ static void dst_asm_deinit(DstAssembler *a) {
|
||||
|
||||
/* Throw some kind of assembly error */
|
||||
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);
|
||||
}
|
||||
#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.parent = parent;
|
||||
a.errmessage = NULL;
|
||||
a.errindex = 0;
|
||||
a.environments_capacity = 0;
|
||||
a.bytecode_count = 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)) {
|
||||
blength++;
|
||||
} else {
|
||||
a.errindex = i;
|
||||
dst_asm_error(&a, "expected assembly instruction");
|
||||
}
|
||||
}
|
||||
@ -631,6 +634,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
|
||||
uint32_t op;
|
||||
const DstInstructionDef *idef;
|
||||
const Dst *t;
|
||||
a.errindex = i;
|
||||
dst_asm_assert(&a, dst_checktype(instr, DST_TUPLE), "expected tuple");
|
||||
t = dst_unwrap_tuple(instr);
|
||||
if (dst_tuple_length(t) == 0) {
|
||||
@ -653,6 +657,7 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
|
||||
} else {
|
||||
dst_asm_error(&a, "bytecode expected");
|
||||
}
|
||||
a.errindex = -1;
|
||||
|
||||
/* Check for source mapping */
|
||||
x = dst_get(s, dst_csymbolv("sourcemap"));
|
||||
|
@ -335,15 +335,13 @@ If no match is found, returns nil"
|
||||
(foreach s (fn [x] (put tab x true)))
|
||||
(keys tab))
|
||||
|
||||
(defn make-env [parent]
|
||||
(defn make-env [parent safe]
|
||||
(def parent (if parent parent _env))
|
||||
(def newenv (setproto @{} parent))
|
||||
(put newenv '_env @{'value newenv})
|
||||
(if (not safe)
|
||||
(put newenv '_env @{'value newenv}))
|
||||
newenv)
|
||||
|
||||
# Remove the reference to the default _env
|
||||
(put _env '_env nil)
|
||||
|
||||
(def run-context
|
||||
"Run a context. This evaluates expressions of dst in an environment,
|
||||
and is encapsulates the parsing, compilation, and evaluation of dst.
|
||||
|
@ -28,7 +28,7 @@
|
||||
(dohandler (string-slice arg 1 2))
|
||||
(do
|
||||
(varset! no-file false)
|
||||
(require arg))))
|
||||
(import arg))))
|
||||
|
||||
(when (or should-repl no-file)
|
||||
(print (string "Dst " VERSION " Copyright (C) 2017-2018 Calvin Rose"))
|
||||
|
Loading…
Reference in New Issue
Block a user