runtime + compiler: dharma, match, cgi blocks, VBD, agentic LLM
Two parallel agent sweeps closing the remaining structural gaps.
== Compiler completions ==
- match codegen: lowers Match into GCC/Clang statement-expression
({ ... }). Patterns: Wildcard, Binding, LitInt (==), LitStr
(str_eq), LitBool. Per-match unique label via state counter.
Verified: classify(0)→"zero", classify(1)→"one", classify(7)→"other".
- cgi block parsing: `cgi "name" { dharma_id, principal, network,
engram }` → CgiBlock AST node → el_cgi_init() emitted as the first
call in main() after el_runtime_init_args. Multiple cgi blocks per
program emit a #error directive. Missing optional fields → EL_NULL.
- VBD compile-time enforcement: parser attaches `decorator: <name>`
to FnDef. Codegen recursively walks fn bodies (Call/BinOp/Not/Neg/
Field/Index/Try/Array/Map/If/For/Match plus Let/Return/Expr/While/
For). If a non-@manager function calls dharma_emit or dharma_field,
emit `#error "VBD violation: ... fn '<name>'"` before the function
body. Verified: @engine fn calling dharma_emit → cc fails with the
message. @manager fn calling dharma_emit → compiles clean.
Three-stage closure: stage1.c == stage2.c == stage3.c (2791 lines
each, byte-identical). dist/platform/elc rebuilt at 165 KB; .prev5
preserved.
== Runtime completions ==
- Real dharma_* primitives, no more stubs. Channel registry,
request/response over HTTP, network-wide spreading activation,
fire-and-forget event emission, blocking dharma_field with
pthread_cond_timedwait (30s default), Hebbian relationship
weights stored as Engram edges between dharma:self and
dharma:peer:<id>, sorted-by-weight peer list. URL/ID arrays
snapshotted before network I/O so mutexes never block on socket.
- New public C contract: el_runtime_dharma_event_arrive(type, payload,
source) — application HTTP handler calls this when /dharma/event
arrives, runtime broadcasts on _dharma_event_cv. Keeps the HTTP
server generic; events flow through the application's router.
- llm_call_agentic real multi-turn loop. Tool registry (mutex-
protected, dlsym-resolved, mirroring http_set_handler). Loop:
build request with tools+messages → POST → dispatch on stop_reason.
end_turn → return text. max_tokens → text + "[truncated]". tool_use
→ walk content[], call registered handler per block, build
tool_result message, append to conversation, loop. Iteration cap
10. Tools not registered return {"error":"tool not registered: X"}
with is_error: true.
- New builtin: llm_register_tool(name, handler_fn_name).
Compile clean: cc -std=c11 -Wall -Wextra -c → zero warnings, zero
errors. Smoke test exercises every new dharma_* primitive +
llm_register_tool round-trip.
Runtime grew 3309→4079 lines (.c, ~155 KB), 312→342 lines (.h).
== Integration ==
Engram rebuilt against the new runtime: 130 KB binary, daemon
swapped on :8742 cleanly, /health and /api/stats both returning
correctly under launchd. No regressions.
== Status of "planned" items in language.md ==
- match codegen → IMPLEMENTED
- cgi block parsing → IMPLEMENTED
- VBD enforcement → IMPLEMENTED
- % operator → IMPLEMENTED (earlier today)
- vessel keyword → lexed (codegen uses package compatible)
- activate construct → still planned (low priority; engram_activate
builtin covers the use case for now)
- sealed block → still planned
- dharma_emit fanout parallelization → potential future work, current
serial behavior matches spec
This commit is contained in:
Vendored
BIN
Binary file not shown.
Vendored
+373
-1
@@ -39,6 +39,8 @@ el_val_t emit_line(el_val_t line);
|
||||
el_val_t emit_blank(void);
|
||||
el_val_t binop_to_c(el_val_t op);
|
||||
el_val_t cg_expr(el_val_t expr);
|
||||
el_val_t next_match_id(void);
|
||||
el_val_t cg_match(el_val_t expr);
|
||||
el_val_t list_contains(el_val_t lst, el_val_t s);
|
||||
el_val_t cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared);
|
||||
el_val_t strip_outer_parens(el_val_t s);
|
||||
@@ -56,6 +58,10 @@ el_val_t build_int_names_for_params(el_val_t params);
|
||||
el_val_t cg_fn(el_val_t stmt);
|
||||
el_val_t is_fndef(el_val_t stmt);
|
||||
el_val_t is_top_level_decl(el_val_t stmt);
|
||||
el_val_t cgi_arg(el_val_t value, el_val_t has_value);
|
||||
el_val_t vbd_is_restricted_name(el_val_t name);
|
||||
el_val_t vbd_expr_has_restricted_call(el_val_t expr);
|
||||
el_val_t vbd_has_restricted_call(el_val_t stmts);
|
||||
el_val_t codegen(el_val_t stmts, el_val_t source);
|
||||
el_val_t compile(el_val_t source);
|
||||
|
||||
@@ -1491,8 +1497,70 @@ el_val_t parse_stmt(el_val_t tokens, el_val_t pos) {
|
||||
}
|
||||
if (str_eq(k, EL_STR("At"))) {
|
||||
el_val_t p = (pos + 1);
|
||||
el_val_t dec_name = tok_value(tokens, p);
|
||||
p = (p + 1);
|
||||
return parse_stmt(tokens, p);
|
||||
el_val_t r = parse_stmt(tokens, p);
|
||||
el_val_t inner = el_get_field(r, EL_STR("node"));
|
||||
el_val_t p2 = el_get_field(r, EL_STR("pos"));
|
||||
el_val_t inner_kind = el_get_field(inner, EL_STR("stmt"));
|
||||
if (str_eq(inner_kind, EL_STR("FnDef"))) {
|
||||
el_val_t with_dec = el_map_new(6, "stmt", EL_STR("FnDef"), "name", el_get_field(inner, EL_STR("name")), "params", el_get_field(inner, EL_STR("params")), "body", el_get_field(inner, EL_STR("body")), "ret_type", el_get_field(inner, EL_STR("ret_type")), "decorator", dec_name);
|
||||
return make_result(with_dec, p2);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
if (str_eq(k, EL_STR("Cgi"))) {
|
||||
el_val_t p = (pos + 1);
|
||||
el_val_t name = tok_value(tokens, p);
|
||||
p = (p + 1);
|
||||
p = expect(tokens, p, EL_STR("LBrace"));
|
||||
el_val_t dharma_id = EL_STR("");
|
||||
el_val_t principal = EL_STR("");
|
||||
el_val_t network = EL_STR("");
|
||||
el_val_t engram = EL_STR("");
|
||||
el_val_t has_dharma_id = 0;
|
||||
el_val_t has_principal = 0;
|
||||
el_val_t has_network = 0;
|
||||
el_val_t has_engram = 0;
|
||||
el_val_t running = 1;
|
||||
while (running) {
|
||||
el_val_t k2 = tok_kind(tokens, p);
|
||||
if (str_eq(k2, EL_STR("RBrace"))) {
|
||||
running = 0;
|
||||
} else {
|
||||
if (str_eq(k2, EL_STR("Eof"))) {
|
||||
running = 0;
|
||||
} else {
|
||||
el_val_t fname = tok_value(tokens, p);
|
||||
p = (p + 1);
|
||||
p = expect(tokens, p, EL_STR("Colon"));
|
||||
el_val_t fval = tok_value(tokens, p);
|
||||
p = (p + 1);
|
||||
if (str_eq(fname, EL_STR("dharma_id"))) {
|
||||
dharma_id = fval;
|
||||
has_dharma_id = 1;
|
||||
}
|
||||
if (str_eq(fname, EL_STR("principal"))) {
|
||||
principal = fval;
|
||||
has_principal = 1;
|
||||
}
|
||||
if (str_eq(fname, EL_STR("network"))) {
|
||||
network = fval;
|
||||
has_network = 1;
|
||||
}
|
||||
if (str_eq(fname, EL_STR("engram"))) {
|
||||
engram = fval;
|
||||
has_engram = 1;
|
||||
}
|
||||
el_val_t k3 = tok_kind(tokens, p);
|
||||
if (str_eq(k3, EL_STR("Comma"))) {
|
||||
p = (p + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
p = expect(tokens, p, EL_STR("RBrace"));
|
||||
return make_result(el_map_new(10, "stmt", EL_STR("CgiBlock"), "name", name, "dharma_id", dharma_id, "principal", principal, "network", network, "engram", engram, "has_dharma_id", has_dharma_id, "has_principal", has_principal, "has_network", has_network, "has_engram", has_engram), p);
|
||||
}
|
||||
el_val_t r = parse_expr(tokens, pos);
|
||||
el_val_t val = el_get_field(r, EL_STR("node"));
|
||||
@@ -1930,10 +1998,78 @@ el_val_t cg_expr(el_val_t expr) {
|
||||
el_val_t cond_c = cg_expr(cond);
|
||||
return el_str_concat(el_str_concat(EL_STR("/* if-expr */ (("), cond_c), EL_STR(") ? (el_val_t)1 : (el_val_t)0)"));
|
||||
}
|
||||
if (str_eq(kind, EL_STR("Match"))) {
|
||||
return cg_match(expr);
|
||||
}
|
||||
return EL_STR("EL_NULL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t next_match_id(void) {
|
||||
el_val_t csv = state_get(EL_STR("__match_counter"));
|
||||
el_val_t n = 0;
|
||||
if (!str_eq(csv, EL_STR(""))) {
|
||||
n = str_to_int(csv);
|
||||
}
|
||||
n = (n + 1);
|
||||
state_set(EL_STR("__match_counter"), native_int_to_str(n));
|
||||
return native_int_to_str(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t cg_match(el_val_t expr) {
|
||||
el_val_t subject = el_get_field(expr, EL_STR("subject"));
|
||||
el_val_t arms = el_get_field(expr, EL_STR("arms"));
|
||||
el_val_t subj_c = cg_expr(subject);
|
||||
el_val_t id = next_match_id();
|
||||
el_val_t subj_var = el_str_concat(EL_STR("_match_subj_"), id);
|
||||
el_val_t result_var = el_str_concat(EL_STR("_match_result_"), id);
|
||||
el_val_t done_label = el_str_concat(EL_STR("_match_done_"), id);
|
||||
el_val_t out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("({ el_val_t "), subj_var), EL_STR(" = ")), subj_c), EL_STR("; el_val_t ")), result_var), EL_STR(" = 0; "));
|
||||
el_val_t n = native_list_len(arms);
|
||||
el_val_t i = 0;
|
||||
while (i < n) {
|
||||
el_val_t arm = native_list_get(arms, i);
|
||||
el_val_t pat = el_get_field(arm, EL_STR("pattern"));
|
||||
el_val_t body = el_get_field(arm, EL_STR("body"));
|
||||
el_val_t pkind = el_get_field(pat, EL_STR("pattern"));
|
||||
el_val_t body_c = cg_expr(body);
|
||||
if (str_eq(pkind, EL_STR("Wildcard"))) {
|
||||
out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("{ ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "));
|
||||
} else {
|
||||
if (str_eq(pkind, EL_STR("Binding"))) {
|
||||
el_val_t bname = el_get_field(pat, EL_STR("name"));
|
||||
out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("{ el_val_t ")), bname), EL_STR(" = ")), subj_var), EL_STR("; ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "));
|
||||
} else {
|
||||
if (str_eq(pkind, EL_STR("LitInt"))) {
|
||||
el_val_t v = el_get_field(pat, EL_STR("value"));
|
||||
out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (")), subj_var), EL_STR(" == ")), v), EL_STR(") { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "));
|
||||
} else {
|
||||
if (str_eq(pkind, EL_STR("LitStr"))) {
|
||||
el_val_t v = el_get_field(pat, EL_STR("value"));
|
||||
out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (str_eq(")), subj_var), EL_STR(", EL_STR(")), c_str_lit(v)), EL_STR("))) { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "));
|
||||
} else {
|
||||
if (str_eq(pkind, EL_STR("LitBool"))) {
|
||||
el_val_t v = el_get_field(pat, EL_STR("value"));
|
||||
el_val_t bv = EL_STR("0");
|
||||
if (str_eq(v, EL_STR("true"))) {
|
||||
bv = EL_STR("1");
|
||||
}
|
||||
out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("if (")), subj_var), EL_STR(" == ")), bv), EL_STR(") { ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "));
|
||||
} else {
|
||||
out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, EL_STR("{ ")), result_var), EL_STR(" = (")), body_c), EL_STR("); goto ")), done_label), EL_STR("; } "));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i = (i + 1);
|
||||
}
|
||||
out = el_str_concat(el_str_concat(el_str_concat(el_str_concat(out, done_label), EL_STR(":; ")), result_var), EL_STR("; })"));
|
||||
return out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t list_contains(el_val_t lst, el_val_t s) {
|
||||
el_val_t n = native_list_len(lst);
|
||||
el_val_t i = 0;
|
||||
@@ -2025,6 +2161,9 @@ el_val_t cg_stmt(el_val_t stmt, el_val_t indent, el_val_t declared) {
|
||||
if (str_eq(kind, EL_STR("Import"))) {
|
||||
return declared;
|
||||
}
|
||||
if (str_eq(kind, EL_STR("CgiBlock"))) {
|
||||
return declared;
|
||||
}
|
||||
return declared;
|
||||
return 0;
|
||||
}
|
||||
@@ -2304,6 +2443,12 @@ el_val_t cg_fn(el_val_t stmt) {
|
||||
el_val_t body = el_get_field(stmt, EL_STR("body"));
|
||||
el_val_t ret_type = el_get_field(stmt, EL_STR("ret_type"));
|
||||
el_val_t params_c = params_to_c(params);
|
||||
el_val_t decorator = el_get_field(stmt, EL_STR("decorator"));
|
||||
if (vbd_has_restricted_call(body)) {
|
||||
if (!str_eq(decorator, EL_STR("manager"))) {
|
||||
emit_line(el_str_concat(el_str_concat(EL_STR("#error \"VBD violation: dharma_emit/dharma_field called from non-@manager fn '"), fn_name), EL_STR("'\"")));
|
||||
}
|
||||
}
|
||||
build_int_names_for_params(params);
|
||||
emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_val_t "), fn_name), EL_STR("(")), params_c), EL_STR(") {")));
|
||||
el_val_t decl = native_list_empty();
|
||||
@@ -2346,11 +2491,221 @@ el_val_t is_top_level_decl(el_val_t stmt) {
|
||||
if (str_eq(kind, EL_STR("Import"))) {
|
||||
return 1;
|
||||
}
|
||||
if (str_eq(kind, EL_STR("CgiBlock"))) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t cgi_arg(el_val_t value, el_val_t has_value) {
|
||||
if (has_value) {
|
||||
return el_str_concat(el_str_concat(EL_STR("EL_STR("), c_str_lit(value)), EL_STR(")"));
|
||||
}
|
||||
return EL_STR("EL_NULL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t vbd_is_restricted_name(el_val_t name) {
|
||||
if (str_eq(name, EL_STR("dharma_emit"))) {
|
||||
return 1;
|
||||
}
|
||||
if (str_eq(name, EL_STR("dharma_field"))) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t vbd_expr_has_restricted_call(el_val_t expr) {
|
||||
el_val_t kind = el_get_field(expr, EL_STR("expr"));
|
||||
if (str_eq(kind, EL_STR("Call"))) {
|
||||
el_val_t func = el_get_field(expr, EL_STR("func"));
|
||||
el_val_t fk = el_get_field(func, EL_STR("expr"));
|
||||
if (str_eq(fk, EL_STR("Ident"))) {
|
||||
el_val_t fname = el_get_field(func, EL_STR("name"));
|
||||
if (vbd_is_restricted_name(fname)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (vbd_expr_has_restricted_call(func)) {
|
||||
return 1;
|
||||
}
|
||||
el_val_t args = el_get_field(expr, EL_STR("args"));
|
||||
el_val_t an = native_list_len(args);
|
||||
el_val_t ai = 0;
|
||||
while (ai < an) {
|
||||
el_val_t a = native_list_get(args, ai);
|
||||
if (vbd_expr_has_restricted_call(a)) {
|
||||
return 1;
|
||||
}
|
||||
ai = (ai + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (str_eq(kind, EL_STR("BinOp"))) {
|
||||
el_val_t l = el_get_field(expr, EL_STR("left"));
|
||||
el_val_t r = el_get_field(expr, EL_STR("right"));
|
||||
if (vbd_expr_has_restricted_call(l)) {
|
||||
return 1;
|
||||
}
|
||||
if (vbd_expr_has_restricted_call(r)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (str_eq(kind, EL_STR("Not"))) {
|
||||
return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner")));
|
||||
}
|
||||
if (str_eq(kind, EL_STR("Neg"))) {
|
||||
return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner")));
|
||||
}
|
||||
if (str_eq(kind, EL_STR("Field"))) {
|
||||
return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("object")));
|
||||
}
|
||||
if (str_eq(kind, EL_STR("Index"))) {
|
||||
if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("object")))) {
|
||||
return 1;
|
||||
}
|
||||
if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("index")))) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (str_eq(kind, EL_STR("Try"))) {
|
||||
return vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("inner")));
|
||||
}
|
||||
if (str_eq(kind, EL_STR("Array"))) {
|
||||
el_val_t elems = el_get_field(expr, EL_STR("elems"));
|
||||
el_val_t n = native_list_len(elems);
|
||||
el_val_t i = 0;
|
||||
while (i < n) {
|
||||
el_val_t e = native_list_get(elems, i);
|
||||
if (vbd_expr_has_restricted_call(e)) {
|
||||
return 1;
|
||||
}
|
||||
i = (i + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (str_eq(kind, EL_STR("Map"))) {
|
||||
el_val_t pairs = el_get_field(expr, EL_STR("pairs"));
|
||||
el_val_t n = native_list_len(pairs);
|
||||
el_val_t i = 0;
|
||||
while (i < n) {
|
||||
el_val_t pair = native_list_get(pairs, i);
|
||||
el_val_t v = el_get_field(pair, EL_STR("value"));
|
||||
if (vbd_expr_has_restricted_call(v)) {
|
||||
return 1;
|
||||
}
|
||||
i = (i + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (str_eq(kind, EL_STR("If"))) {
|
||||
if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("cond")))) {
|
||||
return 1;
|
||||
}
|
||||
if (vbd_has_restricted_call(el_get_field(expr, EL_STR("then")))) {
|
||||
return 1;
|
||||
}
|
||||
if (vbd_has_restricted_call(el_get_field(expr, EL_STR("else")))) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (str_eq(kind, EL_STR("For"))) {
|
||||
if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("list")))) {
|
||||
return 1;
|
||||
}
|
||||
if (vbd_has_restricted_call(el_get_field(expr, EL_STR("body")))) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (str_eq(kind, EL_STR("Match"))) {
|
||||
if (vbd_expr_has_restricted_call(el_get_field(expr, EL_STR("subject")))) {
|
||||
return 1;
|
||||
}
|
||||
el_val_t arms = el_get_field(expr, EL_STR("arms"));
|
||||
el_val_t n = native_list_len(arms);
|
||||
el_val_t i = 0;
|
||||
while (i < n) {
|
||||
el_val_t arm = native_list_get(arms, i);
|
||||
el_val_t body = el_get_field(arm, EL_STR("body"));
|
||||
if (vbd_expr_has_restricted_call(body)) {
|
||||
return 1;
|
||||
}
|
||||
i = (i + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t vbd_has_restricted_call(el_val_t stmts) {
|
||||
el_val_t n = native_list_len(stmts);
|
||||
el_val_t i = 0;
|
||||
while (i < n) {
|
||||
el_val_t s = native_list_get(stmts, i);
|
||||
el_val_t sk = el_get_field(s, EL_STR("stmt"));
|
||||
if (str_eq(sk, EL_STR("Let"))) {
|
||||
if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (str_eq(sk, EL_STR("Return"))) {
|
||||
if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (str_eq(sk, EL_STR("Expr"))) {
|
||||
if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("value")))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (str_eq(sk, EL_STR("While"))) {
|
||||
if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("cond")))) {
|
||||
return 1;
|
||||
}
|
||||
if (vbd_has_restricted_call(el_get_field(s, EL_STR("body")))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (str_eq(sk, EL_STR("For"))) {
|
||||
if (vbd_expr_has_restricted_call(el_get_field(s, EL_STR("list")))) {
|
||||
return 1;
|
||||
}
|
||||
if (vbd_has_restricted_call(el_get_field(s, EL_STR("body")))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
i = (i + 1);
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t codegen(el_val_t stmts, el_val_t source) {
|
||||
el_val_t n_top = native_list_len(stmts);
|
||||
el_val_t cgi_count = 0;
|
||||
el_val_t cgi_block = el_map_new(1, "stmt", EL_STR("None"));
|
||||
el_val_t ti = 0;
|
||||
while (ti < n_top) {
|
||||
el_val_t s = native_list_get(stmts, ti);
|
||||
el_val_t sk = el_get_field(s, EL_STR("stmt"));
|
||||
if (str_eq(sk, EL_STR("CgiBlock"))) {
|
||||
cgi_count = (cgi_count + 1);
|
||||
if (cgi_count == 1) {
|
||||
cgi_block = s;
|
||||
}
|
||||
}
|
||||
ti = (ti + 1);
|
||||
}
|
||||
if (cgi_count > 1) {
|
||||
emit_line(EL_STR("#error \"El: multiple cgi blocks in program (only one allowed)\""));
|
||||
}
|
||||
emit_line(EL_STR("#include <stdint.h>"));
|
||||
emit_line(EL_STR("#include <stdlib.h>"));
|
||||
emit_line(EL_STR("#include \"el_runtime.h\""));
|
||||
@@ -2381,6 +2736,23 @@ el_val_t codegen(el_val_t stmts, el_val_t source) {
|
||||
}
|
||||
emit_line(EL_STR("int main(int argc, char** argv) {"));
|
||||
emit_line(EL_STR(" el_runtime_init_args(argc, argv);"));
|
||||
if (cgi_count >= 1) {
|
||||
el_val_t cname = el_get_field(cgi_block, EL_STR("name"));
|
||||
el_val_t cdid = el_get_field(cgi_block, EL_STR("dharma_id"));
|
||||
el_val_t cprin = el_get_field(cgi_block, EL_STR("principal"));
|
||||
el_val_t cnet = el_get_field(cgi_block, EL_STR("network"));
|
||||
el_val_t ceng = el_get_field(cgi_block, EL_STR("engram"));
|
||||
el_val_t has_did = el_get_field(cgi_block, EL_STR("has_dharma_id"));
|
||||
el_val_t has_prin = el_get_field(cgi_block, EL_STR("has_principal"));
|
||||
el_val_t has_net = el_get_field(cgi_block, EL_STR("has_network"));
|
||||
el_val_t has_eng = el_get_field(cgi_block, EL_STR("has_engram"));
|
||||
el_val_t arg_name = el_str_concat(el_str_concat(EL_STR("EL_STR("), c_str_lit(cname)), EL_STR(")"));
|
||||
el_val_t arg_did = cgi_arg(cdid, has_did);
|
||||
el_val_t arg_prin = cgi_arg(cprin, has_prin);
|
||||
el_val_t arg_net = cgi_arg(cnet, has_net);
|
||||
el_val_t arg_eng = cgi_arg(ceng, has_eng);
|
||||
emit_line(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR(" el_cgi_init("), arg_name), EL_STR(", ")), arg_did), EL_STR(", ")), arg_prin), EL_STR(", ")), arg_net), EL_STR(", ")), arg_eng), EL_STR(");")));
|
||||
}
|
||||
el_val_t main_decl = native_list_empty();
|
||||
i = 0;
|
||||
while (i < n) {
|
||||
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user