mirror of
https://github.com/janet-lang/janet
synced 2024-12-26 08:20:27 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
98a26f5ce3
@ -1,6 +1,15 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## 0.4.0 - ??
|
||||||
|
- Add parser/insert to modify parser state programmatically
|
||||||
|
- Add debug/stacktrace for easy, pretty stacktraces
|
||||||
|
- Remove the status-pp function
|
||||||
|
- Update API to run-context to be much more sane
|
||||||
|
- Add :lflags option to cook/make-native
|
||||||
|
- Disallow NaNs as table or struct keys
|
||||||
|
- Update module resolution paths and format
|
||||||
|
|
||||||
## 0.3.0 - 2019-26-01
|
## 0.3.0 - 2019-26-01
|
||||||
- Add amalgamated build to janet for easier embedding.
|
- Add amalgamated build to janet for easier embedding.
|
||||||
- Add os/date function
|
- Add os/date function
|
||||||
|
@ -175,9 +175,10 @@ Building with emscripten on windows is currently unsupported.
|
|||||||
|
|
||||||
See the examples directory for some example janet code.
|
See the examples directory for some example janet code.
|
||||||
|
|
||||||
## IRC
|
## Discussion
|
||||||
|
|
||||||
Feel free to ask questions and join discussion on [the #janet channel on Freenode](https://webchat.freenode.net/)
|
Feel free to ask questions and join discussion on the [Janet Gitter Channel](https://gitter.im/janet-language/community).
|
||||||
|
Alternatively, check out [the #janet channel on Freenode](https://webchat.freenode.net/)
|
||||||
|
|
||||||
## Why Janet
|
## Why Janet
|
||||||
|
|
||||||
|
@ -27,9 +27,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void janet_panicv(Janet message) {
|
void janet_panicv(Janet message) {
|
||||||
if (janet_vm_fiber != NULL) {
|
if (janet_vm_return_reg != NULL) {
|
||||||
janet_fiber_push(janet_vm_fiber, message);
|
*janet_vm_return_reg = message;
|
||||||
longjmp(janet_vm_fiber->buf, 1);
|
longjmp(*janet_vm_jmp_buf, 1);
|
||||||
} else {
|
} else {
|
||||||
fputs((const char *)janet_formatc("janet top level panic - %v\n", message), stdout);
|
fputs((const char *)janet_formatc("janet top level panic - %v\n", message), stdout);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -1393,18 +1393,23 @@ value, one key will be ignored."
|
|||||||
where
|
where
|
||||||
" around byte "
|
" around byte "
|
||||||
(string (parser/where p))
|
(string (parser/where p))
|
||||||
(or (parser/error p) "unmatched delimiter")))
|
": "
|
||||||
|
(or (parser/error p) "unmatched delimiter")
|
||||||
|
"\n"))
|
||||||
|
|
||||||
(defn bad-compile
|
(defn bad-compile
|
||||||
"Default handler for a compile error."
|
"Default handler for a compile error."
|
||||||
[msg macrof where]
|
[msg macrof where]
|
||||||
(file/write stderr msg " while compiling " where "\n")
|
(file/write stderr "compile error: " msg " while compiling " where "\n")
|
||||||
(when macrof (debug/stacktrace macrof)))
|
(when macrof (debug/stacktrace macrof)))
|
||||||
|
|
||||||
(defn getline
|
(defn getline
|
||||||
"Read a line from stdin into a buffer."
|
"Read a line from stdin into a buffer."
|
||||||
[buf p]
|
[buf p &]
|
||||||
(file/read stdin :line buf))
|
(default buf @"")
|
||||||
|
(when p (file/write stdout p))
|
||||||
|
(file/read stdin :line buf)
|
||||||
|
buf)
|
||||||
|
|
||||||
(defn run-context
|
(defn run-context
|
||||||
"Run a context. This evaluates expressions of janet in an environment,
|
"Run a context. This evaluates expressions of janet in an environment,
|
||||||
@ -1518,7 +1523,7 @@ value, one key will be ignored."
|
|||||||
(error (res :error))))
|
(error (res :error))))
|
||||||
|
|
||||||
(def module/paths
|
(def module/paths
|
||||||
"The list of paths to look for modules. The followig
|
"The list of paths to look for modules. The following
|
||||||
substitutions are preformed on each path. :sys: becomes
|
substitutions are preformed on each path. :sys: becomes
|
||||||
module/*syspath*, :name: becomes the last part of the module
|
module/*syspath*, :name: becomes the last part of the module
|
||||||
name after the last /, and :all: is the module name literally.
|
name after the last /, and :all: is the module name literally.
|
||||||
|
@ -66,6 +66,7 @@ JanetFiber *janet_fiber_reset(JanetFiber *fiber, JanetFunction *callee, int32_t
|
|||||||
fiber->stacktop = newstacktop;
|
fiber->stacktop = newstacktop;
|
||||||
}
|
}
|
||||||
if (janet_fiber_funcframe(fiber, callee)) return NULL;
|
if (janet_fiber_funcframe(fiber, callee)) return NULL;
|
||||||
|
janet_fiber_frame(fiber)->flags |= JANET_STACKFRAME_ENTRANCE;
|
||||||
return fiber;
|
return fiber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,6 +649,39 @@ static Janet cfun_parse_consume(int32_t argc, Janet *argv) {
|
|||||||
return janet_wrap_integer(i);
|
return janet_wrap_integer(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Janet cfun_parse_insert(int32_t argc, Janet *argv) {
|
||||||
|
janet_fixarity(argc, 2);
|
||||||
|
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
|
||||||
|
JanetParseState *s = p->states + p->statecount - 1;
|
||||||
|
if (s->consumer == tokenchar) {
|
||||||
|
janet_parser_consume(p, ' ');
|
||||||
|
p->offset--;
|
||||||
|
s = p->states + p->statecount - 1;
|
||||||
|
}
|
||||||
|
if (s->flags & PFLAG_CONTAINER) {
|
||||||
|
s->argn++;
|
||||||
|
if (p->statecount == 1) p->pending++;
|
||||||
|
push_arg(p, argv[1]);
|
||||||
|
} else if (s->flags & (PFLAG_STRING | PFLAG_LONGSTRING)) {
|
||||||
|
const uint8_t *str = janet_to_string(argv[1]);
|
||||||
|
int32_t slen = janet_string_length(str);
|
||||||
|
size_t newcount = p->bufcount + slen;
|
||||||
|
if (p->bufcap > p->bufcount + slen) {
|
||||||
|
size_t newcap = 2 * newcount;
|
||||||
|
p->buf = realloc(p->buf, newcap);
|
||||||
|
if (p->buf == NULL) {
|
||||||
|
JANET_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
p->bufcap = newcap;
|
||||||
|
}
|
||||||
|
memcpy(p->buf + p->bufcount, str, slen);
|
||||||
|
p->bufcount = newcount;
|
||||||
|
} else {
|
||||||
|
janet_panic("cannot insert value into parser");
|
||||||
|
}
|
||||||
|
return argv[0];
|
||||||
|
}
|
||||||
|
|
||||||
static Janet cfun_parse_has_more(int32_t argc, Janet *argv) {
|
static Janet cfun_parse_has_more(int32_t argc, Janet *argv) {
|
||||||
janet_fixarity(argc, 1);
|
janet_fixarity(argc, 1);
|
||||||
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
|
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
|
||||||
@ -807,6 +840,13 @@ static const JanetReg parse_cfuns[] = {
|
|||||||
"in the byte stream as a tuple (line, column). Lines and columns are counted from "
|
"in the byte stream as a tuple (line, column). Lines and columns are counted from "
|
||||||
"1, (the first byte is line 1, column 1) and a newline is considered ASCII 0x0A.")
|
"1, (the first byte is line 1, column 1) and a newline is considered ASCII 0x0A.")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"parser/insert", cfun_parse_insert,
|
||||||
|
JDOC("(parser/insert parser value)\n\n"
|
||||||
|
"Insert a value into the parser. This means that the parser state can be manipulated "
|
||||||
|
"in between chunks of bytes. This would allow a user to add extra elements to arrays "
|
||||||
|
"and tuples, for example. Returns the parser.")
|
||||||
|
},
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -990,7 +990,6 @@ static uint32_t compile1(Builder *b, Janet peg) {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t *bytecode;
|
uint32_t *bytecode;
|
||||||
Janet *constants;
|
Janet *constants;
|
||||||
uint32_t main_rule;
|
|
||||||
uint32_t num_constants;
|
uint32_t num_constants;
|
||||||
} Peg;
|
} Peg;
|
||||||
|
|
||||||
@ -1009,7 +1008,7 @@ static JanetAbstractType peg_type = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Convert Builder to Peg (Janet Abstract Value) */
|
/* Convert Builder to Peg (Janet Abstract Value) */
|
||||||
static Peg *make_peg(Builder *b, uint32_t main_rule) {
|
static Peg *make_peg(Builder *b) {
|
||||||
size_t bytecode_size = janet_v_count(b->bytecode) * sizeof(uint32_t);
|
size_t bytecode_size = janet_v_count(b->bytecode) * sizeof(uint32_t);
|
||||||
size_t constants_size = janet_v_count(b->constants) * sizeof(Janet);
|
size_t constants_size = janet_v_count(b->constants) * sizeof(Janet);
|
||||||
size_t total_size = bytecode_size + constants_size + sizeof(Peg);
|
size_t total_size = bytecode_size + constants_size + sizeof(Peg);
|
||||||
@ -1018,7 +1017,6 @@ static Peg *make_peg(Builder *b, uint32_t main_rule) {
|
|||||||
peg->bytecode = (uint32_t *)(mem + sizeof(Peg));
|
peg->bytecode = (uint32_t *)(mem + sizeof(Peg));
|
||||||
peg->constants = (Janet *)(mem + sizeof(Peg) + bytecode_size);
|
peg->constants = (Janet *)(mem + sizeof(Peg) + bytecode_size);
|
||||||
peg->num_constants = janet_v_count(b->constants);
|
peg->num_constants = janet_v_count(b->constants);
|
||||||
peg->main_rule = main_rule;
|
|
||||||
memcpy(peg->bytecode, b->bytecode, bytecode_size);
|
memcpy(peg->bytecode, b->bytecode, bytecode_size);
|
||||||
memcpy(peg->constants, b->constants, constants_size);
|
memcpy(peg->constants, b->constants, constants_size);
|
||||||
return peg;
|
return peg;
|
||||||
@ -1035,8 +1033,8 @@ static Peg *compile_peg(Janet x) {
|
|||||||
builder.nexttag = 1;
|
builder.nexttag = 1;
|
||||||
builder.form = x;
|
builder.form = x;
|
||||||
builder.depth = JANET_RECURSION_GUARD;
|
builder.depth = JANET_RECURSION_GUARD;
|
||||||
uint32_t main_rule = compile1(&builder, x);
|
compile1(&builder, x);
|
||||||
Peg *peg = make_peg(&builder, main_rule);
|
Peg *peg = make_peg(&builder);
|
||||||
builder_cleanup(&builder);
|
builder_cleanup(&builder);
|
||||||
return peg;
|
return peg;
|
||||||
}
|
}
|
||||||
@ -1082,7 +1080,7 @@ static Janet cfun_peg_match(int32_t argc, Janet *argv) {
|
|||||||
|
|
||||||
s.constants = peg->constants;
|
s.constants = peg->constants;
|
||||||
s.bytecode = peg->bytecode;
|
s.bytecode = peg->bytecode;
|
||||||
const uint8_t *result = peg_rule(&s, s.bytecode + peg->main_rule, bytes.bytes + start);
|
const uint8_t *result = peg_rule(&s, s.bytecode, bytes.bytes + start);
|
||||||
return result ? janet_wrap_array(s.captures) : janet_wrap_nil();
|
return result ? janet_wrap_array(s.captures) : janet_wrap_nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,11 @@ extern JANET_THREAD_LOCAL int janet_vm_stackn;
|
|||||||
* Set and unset by janet_run. */
|
* Set and unset by janet_run. */
|
||||||
extern JANET_THREAD_LOCAL JanetFiber *janet_vm_fiber;
|
extern JANET_THREAD_LOCAL JanetFiber *janet_vm_fiber;
|
||||||
|
|
||||||
|
/* The current pointer to the inner most jmp_buf. The current
|
||||||
|
* return point for panics. */
|
||||||
|
extern JANET_THREAD_LOCAL jmp_buf *janet_vm_jmp_buf;
|
||||||
|
extern JANET_THREAD_LOCAL Janet *janet_vm_return_reg;
|
||||||
|
|
||||||
/* The global registry for c functions. Used to store meta-data
|
/* The global registry for c functions. Used to store meta-data
|
||||||
* along with otherwise bare c function pointers. */
|
* along with otherwise bare c function pointers. */
|
||||||
extern JANET_THREAD_LOCAL JanetTable *janet_vm_registry;
|
extern JANET_THREAD_LOCAL JanetTable *janet_vm_registry;
|
||||||
|
@ -228,7 +228,7 @@ static double convert(
|
|||||||
bignat_lshift_n(mant, shamt);
|
bignat_lshift_n(mant, shamt);
|
||||||
exponent2 -= shamt * BIGNAT_NBIT;
|
exponent2 -= shamt * BIGNAT_NBIT;
|
||||||
for (;exponent < -3; exponent += 4) bignat_div(mant, base * base * base * base);
|
for (;exponent < -3; exponent += 4) bignat_div(mant, base * base * base * base);
|
||||||
for (;exponent < -2; exponent += 2) bignat_div(mant, base * base);
|
for (;exponent < -1; exponent += 2) bignat_div(mant, base * base);
|
||||||
for (;exponent < 0; exponent += 1) bignat_div(mant, base);
|
for (;exponent < 0; exponent += 1) bignat_div(mant, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
JANET_THREAD_LOCAL JanetTable *janet_vm_registry;
|
JANET_THREAD_LOCAL JanetTable *janet_vm_registry;
|
||||||
JANET_THREAD_LOCAL int janet_vm_stackn = 0;
|
JANET_THREAD_LOCAL int janet_vm_stackn = 0;
|
||||||
JANET_THREAD_LOCAL JanetFiber *janet_vm_fiber = NULL;
|
JANET_THREAD_LOCAL JanetFiber *janet_vm_fiber = NULL;
|
||||||
|
JANET_THREAD_LOCAL Janet *janet_vm_return_reg = NULL;
|
||||||
|
JANET_THREAD_LOCAL jmp_buf *janet_vm_jmp_buf = NULL;
|
||||||
|
|
||||||
/* Virtual registers
|
/* Virtual registers
|
||||||
*
|
*
|
||||||
@ -148,7 +150,7 @@ static void *op_lookup[255] = {
|
|||||||
} while (0)
|
} while (0)
|
||||||
#define vm_return(sig, val) do { \
|
#define vm_return(sig, val) do { \
|
||||||
vm_commit(); \
|
vm_commit(); \
|
||||||
janet_fiber_push(fiber, (val)); \
|
janet_vm_return_reg[0] = (val); \
|
||||||
return (sig); \
|
return (sig); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@ -283,8 +285,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
|
|||||||
VM_OP(JOP_RETURN)
|
VM_OP(JOP_RETURN)
|
||||||
{
|
{
|
||||||
Janet retval = stack[D];
|
Janet retval = stack[D];
|
||||||
|
int entrance_frame = janet_stack_frame(stack)->flags & JANET_STACKFRAME_ENTRANCE;
|
||||||
janet_fiber_popframe(fiber);
|
janet_fiber_popframe(fiber);
|
||||||
if (fiber->frame == 0) vm_return(JANET_SIGNAL_OK, retval);
|
if (entrance_frame) vm_return(JANET_SIGNAL_OK, retval);
|
||||||
vm_restore();
|
vm_restore();
|
||||||
stack[A] = retval;
|
stack[A] = retval;
|
||||||
vm_checkgc_pcnext();
|
vm_checkgc_pcnext();
|
||||||
@ -293,8 +296,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
|
|||||||
VM_OP(JOP_RETURN_NIL)
|
VM_OP(JOP_RETURN_NIL)
|
||||||
{
|
{
|
||||||
Janet retval = janet_wrap_nil();
|
Janet retval = janet_wrap_nil();
|
||||||
|
int entrance_frame = janet_stack_frame(stack)->flags & JANET_STACKFRAME_ENTRANCE;
|
||||||
janet_fiber_popframe(fiber);
|
janet_fiber_popframe(fiber);
|
||||||
if (fiber->frame == 0) vm_return(JANET_SIGNAL_OK, retval);
|
if (entrance_frame) vm_return(JANET_SIGNAL_OK, retval);
|
||||||
vm_restore();
|
vm_restore();
|
||||||
stack[A] = retval;
|
stack[A] = retval;
|
||||||
vm_checkgc_pcnext();
|
vm_checkgc_pcnext();
|
||||||
@ -581,7 +585,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
|
|||||||
janet_fiber_cframe(fiber, janet_unwrap_cfunction(callee));
|
janet_fiber_cframe(fiber, janet_unwrap_cfunction(callee));
|
||||||
Janet ret = janet_unwrap_cfunction(callee)(argc, fiber->data + fiber->frame);
|
Janet ret = janet_unwrap_cfunction(callee)(argc, fiber->data + fiber->frame);
|
||||||
janet_fiber_popframe(fiber);
|
janet_fiber_popframe(fiber);
|
||||||
if (fiber->frame == 0) vm_return(JANET_SIGNAL_OK, ret);
|
/*if (fiber->frame == 0) vm_return(JANET_SIGNAL_OK, ret);*/
|
||||||
stack = fiber->data + fiber->frame;
|
stack = fiber->data + fiber->frame;
|
||||||
stack[A] = ret;
|
stack[A] = ret;
|
||||||
vm_checkgc_pcnext();
|
vm_checkgc_pcnext();
|
||||||
@ -614,6 +618,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
|
|||||||
vm_checkgc_next();
|
vm_checkgc_next();
|
||||||
} else {
|
} else {
|
||||||
Janet retreg;
|
Janet retreg;
|
||||||
|
int entrance_frame = janet_stack_frame(stack)->flags & JANET_STACKFRAME_ENTRANCE;
|
||||||
vm_commit();
|
vm_commit();
|
||||||
if (janet_checktype(callee, JANET_CFUNCTION)) {
|
if (janet_checktype(callee, JANET_CFUNCTION)) {
|
||||||
int32_t argc = fiber->stacktop - fiber->stackstart;
|
int32_t argc = fiber->stacktop - fiber->stackstart;
|
||||||
@ -624,7 +629,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
|
|||||||
retreg = call_nonfn(fiber, callee);
|
retreg = call_nonfn(fiber, callee);
|
||||||
}
|
}
|
||||||
janet_fiber_popframe(fiber);
|
janet_fiber_popframe(fiber);
|
||||||
if (fiber->frame == 0)
|
if (entrance_frame)
|
||||||
vm_return(JANET_SIGNAL_OK, retreg);
|
vm_return(JANET_SIGNAL_OK, retreg);
|
||||||
vm_restore();
|
vm_restore();
|
||||||
stack[A] = retreg;
|
stack[A] = retreg;
|
||||||
@ -755,39 +760,45 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
|
Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
|
||||||
|
Janet ret;
|
||||||
|
Janet *old_return_reg = janet_vm_return_reg;
|
||||||
|
|
||||||
|
/* Check entry conditions */
|
||||||
|
if (!janet_vm_fiber)
|
||||||
|
janet_panic("janet_call failed because there is no current fiber");
|
||||||
if (janet_vm_stackn >= JANET_RECURSION_GUARD)
|
if (janet_vm_stackn >= JANET_RECURSION_GUARD)
|
||||||
janet_panic("C stack recursed too deeply");
|
janet_panic("C stack recursed too deeply");
|
||||||
JanetFiber *fiber = janet_fiber(fun, 64, argc, argv);
|
|
||||||
if (!fiber)
|
/* Push frame */
|
||||||
janet_panic("arity mismatch");
|
janet_fiber_pushn(janet_vm_fiber, argv, argc);
|
||||||
JanetFiber *old_fiber = janet_vm_fiber;
|
if (janet_fiber_funcframe(janet_vm_fiber, fun)) {
|
||||||
janet_vm_fiber = fiber;
|
janet_panicf("arity mismatch in %v", fun);
|
||||||
janet_gcroot(janet_wrap_fiber(fiber));
|
}
|
||||||
|
janet_fiber_frame(janet_vm_fiber)->flags |= JANET_STACKFRAME_ENTRANCE;
|
||||||
|
|
||||||
|
/* Set up */
|
||||||
int32_t oldn = janet_vm_stackn++;
|
int32_t oldn = janet_vm_stackn++;
|
||||||
int handle = janet_gclock();
|
int handle = janet_gclock();
|
||||||
|
janet_vm_return_reg = &ret;
|
||||||
|
|
||||||
JanetSignal signal;
|
/* Run vm */
|
||||||
if (setjmp(fiber->buf)) {
|
JanetSignal signal = run_vm(janet_vm_fiber,
|
||||||
signal = JANET_SIGNAL_ERROR;
|
janet_wrap_nil(),
|
||||||
} else {
|
JANET_STATUS_ALIVE);
|
||||||
signal = run_vm(fiber, janet_wrap_nil(), JANET_STATUS_NEW);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Teardown */
|
||||||
|
janet_vm_return_reg = old_return_reg;
|
||||||
janet_vm_stackn = oldn;
|
janet_vm_stackn = oldn;
|
||||||
janet_vm_fiber = old_fiber;
|
|
||||||
Janet ret = fiber->data[fiber->stacktop - 1];
|
|
||||||
janet_gcunroot(janet_wrap_fiber(fiber));
|
|
||||||
janet_gcunlock(handle);
|
janet_gcunlock(handle);
|
||||||
if (signal == JANET_SIGNAL_ERROR) {
|
|
||||||
old_fiber->child = fiber;
|
if (signal != JANET_SIGNAL_OK) janet_panicv(ret);
|
||||||
janet_fiber_set_status(fiber, signal);
|
|
||||||
janet_panicv(ret);
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter the main vm loop */
|
/* Enter the main vm loop */
|
||||||
JanetSignal janet_continue(JanetFiber *fiber, Janet in, Janet *out) {
|
JanetSignal janet_continue(JanetFiber *fiber, Janet in, Janet *out) {
|
||||||
|
jmp_buf buf;
|
||||||
|
|
||||||
/* Check conditions */
|
/* Check conditions */
|
||||||
JanetFiberStatus old_status = janet_fiber_status(fiber);
|
JanetFiberStatus old_status = janet_fiber_status(fiber);
|
||||||
@ -820,15 +831,19 @@ JanetSignal janet_continue(JanetFiber *fiber, Janet in, Janet *out) {
|
|||||||
int32_t oldn = janet_vm_stackn++;
|
int32_t oldn = janet_vm_stackn++;
|
||||||
int handle = janet_vm_gc_suspend;
|
int handle = janet_vm_gc_suspend;
|
||||||
JanetFiber *old_vm_fiber = janet_vm_fiber;
|
JanetFiber *old_vm_fiber = janet_vm_fiber;
|
||||||
|
jmp_buf *old_vm_jmp_buf = janet_vm_jmp_buf;
|
||||||
|
Janet *old_vm_return_reg = janet_vm_return_reg;
|
||||||
|
|
||||||
/* Setup fiber */
|
/* Setup fiber */
|
||||||
janet_vm_fiber = fiber;
|
janet_vm_fiber = fiber;
|
||||||
janet_gcroot(janet_wrap_fiber(fiber));
|
janet_gcroot(janet_wrap_fiber(fiber));
|
||||||
janet_fiber_set_status(fiber, JANET_STATUS_ALIVE);
|
janet_fiber_set_status(fiber, JANET_STATUS_ALIVE);
|
||||||
|
janet_vm_return_reg = out;
|
||||||
|
janet_vm_jmp_buf = &buf;
|
||||||
|
|
||||||
/* Run loop */
|
/* Run loop */
|
||||||
JanetSignal signal;
|
JanetSignal signal;
|
||||||
if (setjmp(fiber->buf)) {
|
if (setjmp(buf)) {
|
||||||
signal = JANET_SIGNAL_ERROR;
|
signal = JANET_SIGNAL_ERROR;
|
||||||
} else {
|
} else {
|
||||||
signal = run_vm(fiber, in, old_status);
|
signal = run_vm(fiber, in, old_status);
|
||||||
@ -842,9 +857,10 @@ JanetSignal janet_continue(JanetFiber *fiber, Janet in, Janet *out) {
|
|||||||
janet_vm_gc_suspend = handle;
|
janet_vm_gc_suspend = handle;
|
||||||
janet_vm_fiber = old_vm_fiber;
|
janet_vm_fiber = old_vm_fiber;
|
||||||
janet_vm_stackn = oldn;
|
janet_vm_stackn = oldn;
|
||||||
|
janet_vm_return_reg = old_vm_return_reg;
|
||||||
|
janet_vm_jmp_buf = old_vm_jmp_buf;
|
||||||
|
|
||||||
/* Pop error or return value from fiber stack */
|
/* Pop error or return value from fiber stack */
|
||||||
*out = fiber->data[--fiber->stacktop];
|
|
||||||
|
|
||||||
return signal;
|
return signal;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ extern "C" {
|
|||||||
|
|
||||||
/***** START SECTION CONFIG *****/
|
/***** START SECTION CONFIG *****/
|
||||||
|
|
||||||
#define JANET_VERSION "0.3.0"
|
#define JANET_VERSION "0.4.0"
|
||||||
|
|
||||||
#ifndef JANET_BUILD
|
#ifndef JANET_BUILD
|
||||||
#define JANET_BUILD "local"
|
#define JANET_BUILD "local"
|
||||||
@ -603,12 +603,14 @@ struct JanetFiber {
|
|||||||
int32_t capacity;
|
int32_t capacity;
|
||||||
int32_t maxstack; /* Arbitrary defined limit for stack overflow */
|
int32_t maxstack; /* Arbitrary defined limit for stack overflow */
|
||||||
int32_t flags; /* Various flags */
|
int32_t flags; /* Various flags */
|
||||||
jmp_buf buf; /* Handle errors */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Mark if a stack frame is a tail call for debugging */
|
/* Mark if a stack frame is a tail call for debugging */
|
||||||
#define JANET_STACKFRAME_TAILCALL 1
|
#define JANET_STACKFRAME_TAILCALL 1
|
||||||
|
|
||||||
|
/* Mark if a stack frame is an entrance frame */
|
||||||
|
#define JANET_STACKFRAME_ENTRANCE 2
|
||||||
|
|
||||||
/* A stack frame on the fiber. Is stored along with the stack values. */
|
/* A stack frame on the fiber. Is stored along with the stack values. */
|
||||||
struct JanetStackFrame {
|
struct JanetStackFrame {
|
||||||
JanetFunction *func;
|
JanetFunction *func;
|
||||||
|
@ -24,11 +24,11 @@
|
|||||||
|
|
||||||
/* Common */
|
/* Common */
|
||||||
Janet janet_line_getter(int32_t argc, Janet *argv) {
|
Janet janet_line_getter(int32_t argc, Janet *argv) {
|
||||||
janet_fixarity(argc, 2);
|
janet_arity(argc, 0, 2);
|
||||||
const uint8_t *str = janet_getstring(argv, 0);
|
const char *str = (argc >= 1) ? (const char *) janet_getstring(argv, 0) : "";
|
||||||
JanetBuffer *buf = janet_getbuffer(argv, 1);
|
JanetBuffer *buf = (argc >= 2) ? janet_getbuffer(argv, 1) : janet_buffer(10);
|
||||||
janet_line_get(str, buf);
|
janet_line_get(str, buf);
|
||||||
return argv[0];
|
return janet_wrap_buffer(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void simpleline(JanetBuffer *buffer) {
|
static void simpleline(JanetBuffer *buffer) {
|
||||||
@ -55,8 +55,8 @@ void janet_line_deinit() {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
void janet_line_get(const uint8_t *p, JanetBuffer *buffer) {
|
void janet_line_get(const char *p, JanetBuffer *buffer) {
|
||||||
fputs((const char *)p, stdout);
|
fputs(p, stdout);
|
||||||
simpleline(buffer);
|
simpleline(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,8 +444,8 @@ static int checktermsupport() {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void janet_line_get(const uint8_t *p, JanetBuffer *buffer) {
|
void janet_line_get(const char *p, JanetBuffer *buffer) {
|
||||||
prompt = (const char *)p;
|
prompt = p;
|
||||||
buffer->count = 0;
|
buffer->count = 0;
|
||||||
historyi = 0;
|
historyi = 0;
|
||||||
if (!isatty(STDIN_FILENO) || !checktermsupport()) {
|
if (!isatty(STDIN_FILENO) || !checktermsupport()) {
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
void janet_line_init();
|
void janet_line_init();
|
||||||
void janet_line_deinit();
|
void janet_line_deinit();
|
||||||
|
|
||||||
void janet_line_get(const uint8_t *p, JanetBuffer *buffer);
|
void janet_line_get(const char *p, JanetBuffer *buffer);
|
||||||
Janet janet_line_getter(int32_t argc, Janet *argv);
|
Janet janet_line_getter(int32_t argc, Janet *argv);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -44,7 +44,7 @@ static int enter_loop(void) {
|
|||||||
Janet ret;
|
Janet ret;
|
||||||
JanetSignal status = janet_continue(repl_fiber, janet_wrap_nil(), &ret);
|
JanetSignal status = janet_continue(repl_fiber, janet_wrap_nil(), &ret);
|
||||||
if (status == JANET_SIGNAL_ERROR) {
|
if (status == JANET_SIGNAL_ERROR) {
|
||||||
janet_stacktrace(repl_fiber, "runtime", ret);
|
janet_stacktrace(repl_fiber, ret);
|
||||||
janet_deinit();
|
janet_deinit();
|
||||||
repl_fiber = NULL;
|
repl_fiber = NULL;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -65,8 +65,8 @@
|
|||||||
# as the version being generated
|
# as the version being generated
|
||||||
(print "#define JANET_BUILD \"" janet/build "\"")
|
(print "#define JANET_BUILD \"" janet/build "\"")
|
||||||
|
|
||||||
(print ```#define JANET_AMALG
|
(print ```#define JANET_AMALG```)
|
||||||
#include "janet.h"```)
|
(print ```#include "janet.h"```)
|
||||||
|
|
||||||
(each h headers (dofile h))
|
(each h headers (dofile h))
|
||||||
(each s sources (dofile s))
|
(each s sources (dofile s))
|
||||||
|
55
tools/bars.janet
Normal file
55
tools/bars.janet
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# A flexible templater for janet. Compiles
|
||||||
|
# templates to janet functions that produce buffers.
|
||||||
|
|
||||||
|
(defn template
|
||||||
|
"Compile a template string into a function"
|
||||||
|
[source]
|
||||||
|
|
||||||
|
# State for compilation machine
|
||||||
|
(def p (parser/new))
|
||||||
|
(def forms @[])
|
||||||
|
|
||||||
|
(defn parse-chunk
|
||||||
|
"Parse a string and push produced values to forms."
|
||||||
|
[chunk]
|
||||||
|
(parser/consume p chunk)
|
||||||
|
(while (parser/has-more p)
|
||||||
|
(array/push forms (parser/produce p)))
|
||||||
|
(if (= :error (parser/status p))
|
||||||
|
(error (parser/error p))))
|
||||||
|
|
||||||
|
(defn code-chunk
|
||||||
|
"Parse all the forms in str and return them
|
||||||
|
in a tuple prefixed with 'do."
|
||||||
|
[str]
|
||||||
|
(parse-chunk str)
|
||||||
|
true)
|
||||||
|
|
||||||
|
(defn string-chunk
|
||||||
|
"Insert string chunk into parser"
|
||||||
|
[str]
|
||||||
|
(parser/insert p str)
|
||||||
|
(parse-chunk "")
|
||||||
|
true)
|
||||||
|
|
||||||
|
# Run peg
|
||||||
|
(def grammar
|
||||||
|
~{:code-chunk (* "{%" (drop (cmt '(any (if-not "%}" 1)) ,code-chunk)) "%}")
|
||||||
|
:main-chunk (drop (cmt '(any (if-not "{%" 1)) ,string-chunk))
|
||||||
|
:main (any (+ :code-chunk :main-chunk (error "")))})
|
||||||
|
(def parts (peg/match grammar source))
|
||||||
|
|
||||||
|
# Check errors in template and parser
|
||||||
|
(unless parts (error "invalid template syntax"))
|
||||||
|
(parse-chunk "\n")
|
||||||
|
(case (parser/status p)
|
||||||
|
:pending (error (string "unfinished parser state " (parser/state p)))
|
||||||
|
:error (error (parser/error p)))
|
||||||
|
|
||||||
|
# Make ast from forms
|
||||||
|
(def ast ~(fn [params &] (default params @{}) (,buffer ;forms)))
|
||||||
|
|
||||||
|
(def ctor (compile ast *env* source))
|
||||||
|
(if-not (function? ctor)
|
||||||
|
(error (string "could not compile template")))
|
||||||
|
(ctor))
|
Loading…
Reference in New Issue
Block a user