mirror of
https://github.com/janet-lang/janet
synced 2025-01-26 07:06:51 +00:00
Update sourcemapping structure. Add seqs example file.
This commit is contained in:
parent
5738f6c8b1
commit
e8dfe673f2
82
examples/lazyseqs.dst
Normal file
82
examples/lazyseqs.dst
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# An example implementation of functional, lazy
|
||||||
|
# sequences, like in clojure.
|
||||||
|
# Use with (import "./path/to/this/file" :prefix "seq/")
|
||||||
|
|
||||||
|
(defn- mem0 [f]
|
||||||
|
"Memoize a 0 arity function."
|
||||||
|
(var state nil)
|
||||||
|
(var loaded nil)
|
||||||
|
(fn []
|
||||||
|
(if loaded
|
||||||
|
state
|
||||||
|
(do
|
||||||
|
(def n (f))
|
||||||
|
(varset! state n)
|
||||||
|
(varset! loaded true)
|
||||||
|
n))))
|
||||||
|
|
||||||
|
(defmacro delay
|
||||||
|
"Macro for lazy evaluation"
|
||||||
|
[x] (tuple mem0 (tuple 'fn [] x)))
|
||||||
|
|
||||||
|
# Use tuples instead of structs to save memory
|
||||||
|
(def HEAD :private 0)
|
||||||
|
(def TAIL :private 1)
|
||||||
|
|
||||||
|
(defn empty-seq
|
||||||
|
"The empty sequence."
|
||||||
|
[] nil)
|
||||||
|
|
||||||
|
(defn cons
|
||||||
|
"Create a new sequence by prepending a value to the original sequence."
|
||||||
|
[h t]
|
||||||
|
(delay (tuple h t)))
|
||||||
|
|
||||||
|
(defn empty?
|
||||||
|
"Check if a sequence is empty."
|
||||||
|
[s]
|
||||||
|
(not (s)))
|
||||||
|
|
||||||
|
(defn head
|
||||||
|
"Get the next value of the sequence."
|
||||||
|
[s]
|
||||||
|
(get (s) HEAD))
|
||||||
|
|
||||||
|
(defn tail
|
||||||
|
"Get the rest of a sequence"
|
||||||
|
[s]
|
||||||
|
(get (s) TAIL))
|
||||||
|
|
||||||
|
(defn range
|
||||||
|
"Return a sequence of integers [start, end)."
|
||||||
|
[start end]
|
||||||
|
(if (< start end)
|
||||||
|
(cons start (range (+ 1 start) end))
|
||||||
|
empty-seq))
|
||||||
|
|
||||||
|
(defn map
|
||||||
|
"Return a sequence that is the result of apply f to each value in s."
|
||||||
|
[f s]
|
||||||
|
(if (s) (cons (f (head s)) (map f (tail s))) empty-seq))
|
||||||
|
|
||||||
|
(defn realize
|
||||||
|
"Force evaluation of a lazy sequence."
|
||||||
|
[s]
|
||||||
|
(when (s) (realize (tail s))))
|
||||||
|
|
||||||
|
(defn realize-map [f s]
|
||||||
|
"Evaluate f on each member of the sequence. Forces evaluation."
|
||||||
|
(when (s) (f (head s)) (realize-map f (tail s))))
|
||||||
|
|
||||||
|
(defn drop
|
||||||
|
"Ignores the first n values of the sequence and returns the rest."
|
||||||
|
[n s]
|
||||||
|
(if (s) (if (zero? n) s (drop (- n 1) (tail s))) empty-seq))
|
||||||
|
|
||||||
|
(defn take
|
||||||
|
"Returns at most the first n values of s."
|
||||||
|
[n s]
|
||||||
|
(if (and (s) (pos? n))
|
||||||
|
(cons (head s) (take (- n 1) (tail s)))
|
||||||
|
empty-seq))
|
||||||
|
|
@ -658,10 +658,11 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
|
|||||||
x = dst_get(s, dst_csymbolv("sourcemap"));
|
x = dst_get(s, dst_csymbolv("sourcemap"));
|
||||||
if (dst_seq_view(x, &arr, &count)) {
|
if (dst_seq_view(x, &arr, &count)) {
|
||||||
dst_asm_assert(&a, count == def->bytecode_length, "sourcemap must have the same length as the bytecode");
|
dst_asm_assert(&a, count == def->bytecode_length, "sourcemap must have the same length as the bytecode");
|
||||||
def->sourcemap = malloc(sizeof(int32_t) * 2 * count);
|
def->sourcemap = malloc(sizeof(DstSourceMapping) * count);
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
const Dst *tup;
|
const Dst *tup;
|
||||||
Dst entry = arr[i];
|
Dst entry = arr[i];
|
||||||
|
DstSourceMapping mapping;
|
||||||
if (!dst_checktype(entry, DST_TUPLE)) {
|
if (!dst_checktype(entry, DST_TUPLE)) {
|
||||||
dst_asm_error(&a, "expected tuple");
|
dst_asm_error(&a, "expected tuple");
|
||||||
}
|
}
|
||||||
@ -672,8 +673,9 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
|
|||||||
if (!dst_checktype(tup[1], DST_INTEGER)) {
|
if (!dst_checktype(tup[1], DST_INTEGER)) {
|
||||||
dst_asm_error(&a, "expected integer");
|
dst_asm_error(&a, "expected integer");
|
||||||
}
|
}
|
||||||
def->sourcemap[2*i] = dst_unwrap_integer(tup[0]);
|
mapping.start = dst_unwrap_integer(tup[0]);
|
||||||
def->sourcemap[2*i+1] = dst_unwrap_integer(tup[1]);
|
mapping.end = dst_unwrap_integer(tup[1]);
|
||||||
|
def->sourcemap[i] = mapping;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,11 +833,12 @@ Dst dst_disasm(DstFuncDef *def) {
|
|||||||
/* Add source map */
|
/* Add source map */
|
||||||
if (NULL != def->sourcemap) {
|
if (NULL != def->sourcemap) {
|
||||||
DstArray *sourcemap = dst_array(def->bytecode_length);
|
DstArray *sourcemap = dst_array(def->bytecode_length);
|
||||||
for (i = 0; i < def->bytecode_length * 2; i += 2) {
|
for (i = 0; i < def->bytecode_length; i++) {
|
||||||
Dst *t = dst_tuple_begin(2);
|
Dst *t = dst_tuple_begin(2);
|
||||||
t[0] = dst_wrap_integer(def->sourcemap[i]);
|
DstSourceMapping mapping = def->sourcemap[i];
|
||||||
t[1] = dst_wrap_integer(def->sourcemap[i + 1]);
|
t[0] = dst_wrap_integer(mapping.start);
|
||||||
sourcemap->data[i / 2] = dst_wrap_tuple(dst_tuple_end(t));
|
t[1] = dst_wrap_integer(mapping.end);
|
||||||
|
sourcemap->data[i] = dst_wrap_tuple(dst_tuple_end(t));
|
||||||
}
|
}
|
||||||
sourcemap->count = def->bytecode_length;
|
sourcemap->count = def->bytecode_length;
|
||||||
dst_table_put(ret, dst_csymbolv("sourcemap"), dst_wrap_array(sourcemap));
|
dst_table_put(ret, dst_csymbolv("sourcemap"), dst_wrap_array(sourcemap));
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
# Bootstrap the dst environment
|
||||||
|
# Copyright 2018 (C) Calvin Rose
|
||||||
|
|
||||||
# Capture the current env
|
# Capture the current env
|
||||||
(var *env*
|
(var *env*
|
||||||
@ -26,6 +28,12 @@
|
|||||||
(def args (array-concat [] name :macro more))
|
(def args (array-concat [] name :macro more))
|
||||||
(apply defn* args))))
|
(apply defn* args))))
|
||||||
|
|
||||||
|
(defmacro defmacro-
|
||||||
|
"Define a private macro that will not be exported."
|
||||||
|
[name & more]
|
||||||
|
(apply tuple (array-concat
|
||||||
|
['defmacro name :private] more)))
|
||||||
|
|
||||||
(defmacro defn-
|
(defmacro defn-
|
||||||
"Define a private function that will not be exported."
|
"Define a private function that will not be exported."
|
||||||
[name & more]
|
[name & more]
|
||||||
@ -36,6 +44,8 @@
|
|||||||
(defn odd? [x] (== 1 (% x 2)))
|
(defn odd? [x] (== 1 (% x 2)))
|
||||||
(defn nil? [x] (= x nil))
|
(defn nil? [x] (= x nil))
|
||||||
(defn zero? [x] (== x 0))
|
(defn zero? [x] (== x 0))
|
||||||
|
(defn pos? [x] (> x 0))
|
||||||
|
(defn neg? [x] (< x 0))
|
||||||
(defn one? [x] (== x 1))
|
(defn one? [x] (== x 1))
|
||||||
(defn inc [x] (+ x 1))
|
(defn inc [x] (+ x 1))
|
||||||
(defn dec [x] (- x 1))
|
(defn dec [x] (- x 1))
|
||||||
|
@ -903,20 +903,22 @@ DstFuncDef *dstc_pop_funcdef(DstCompiler *c) {
|
|||||||
dst_v__cnt(c->buffer) = scope.bytecode_start;
|
dst_v__cnt(c->buffer) = scope.bytecode_start;
|
||||||
if (NULL != c->mapbuffer) {
|
if (NULL != c->mapbuffer) {
|
||||||
int32_t i;
|
int32_t i;
|
||||||
size_t s = sizeof(int32_t) * 2 * dst_v_count(c->mapbuffer);
|
size_t s = sizeof(DstSourceMapping) * dst_v_count(c->mapbuffer);
|
||||||
def->sourcemap = malloc(2 * s);
|
def->sourcemap = malloc(s);
|
||||||
if (NULL == def->sourcemap) {
|
if (NULL == def->sourcemap) {
|
||||||
DST_OUT_OF_MEMORY;
|
DST_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
for (i = 0; i < dst_v_count(c->mapbuffer); i++) {
|
for (i = 0; i < dst_v_count(c->mapbuffer); i++) {
|
||||||
DstAst *a = c->mapbuffer[i];
|
DstAst *a = c->mapbuffer[i];
|
||||||
|
DstSourceMapping mapping;
|
||||||
if (a) {
|
if (a) {
|
||||||
def->sourcemap[2 * i] = a->source_start;
|
mapping.start = a->source_start;
|
||||||
def->sourcemap[2 * i + 1] = a->source_end;
|
mapping.end = a->source_end;
|
||||||
} else {
|
} else {
|
||||||
def->sourcemap[2 * i] = -1;
|
mapping.start = -1;
|
||||||
def->sourcemap[2 * i + 1] = -1;
|
mapping.end = -1;
|
||||||
}
|
}
|
||||||
|
def->sourcemap[i] = mapping;
|
||||||
}
|
}
|
||||||
dst_v__cnt(c->mapbuffer) = scope.bytecode_start;
|
dst_v__cnt(c->mapbuffer) = scope.bytecode_start;
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ typedef struct DstAbstractType DstAbstractType;
|
|||||||
typedef struct DstArgs DstArgs;
|
typedef struct DstArgs DstArgs;
|
||||||
typedef struct DstAst DstAst;
|
typedef struct DstAst DstAst;
|
||||||
typedef struct DstReg DstReg;
|
typedef struct DstReg DstReg;
|
||||||
|
typedef struct DstSourceMapping DstSourceMapping;
|
||||||
typedef int (*DstCFunction)(DstArgs args);
|
typedef int (*DstCFunction)(DstArgs args);
|
||||||
|
|
||||||
/* Basic types for all Dst Values */
|
/* Basic types for all Dst Values */
|
||||||
@ -378,6 +379,11 @@ struct DstKV {
|
|||||||
#define DST_FUNCDEF_FLAG_VARARG 1
|
#define DST_FUNCDEF_FLAG_VARARG 1
|
||||||
#define DST_FUNCDEF_FLAG_NEEDSENV 4
|
#define DST_FUNCDEF_FLAG_NEEDSENV 4
|
||||||
|
|
||||||
|
struct DstSourceMapping {
|
||||||
|
int32_t start;
|
||||||
|
int32_t end;
|
||||||
|
};
|
||||||
|
|
||||||
/* A function definition. Contains information needed to instantiate closures. */
|
/* A function definition. Contains information needed to instantiate closures. */
|
||||||
struct DstFuncDef {
|
struct DstFuncDef {
|
||||||
int32_t *environments; /* Which environments to capture from parent. */
|
int32_t *environments; /* Which environments to capture from parent. */
|
||||||
@ -386,7 +392,7 @@ struct DstFuncDef {
|
|||||||
uint32_t *bytecode;
|
uint32_t *bytecode;
|
||||||
|
|
||||||
/* Various debug information */
|
/* Various debug information */
|
||||||
int32_t *sourcemap;
|
DstSourceMapping *sourcemap;
|
||||||
const uint8_t *source;
|
const uint8_t *source;
|
||||||
const uint8_t *sourcepath;
|
const uint8_t *sourcepath;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user