Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b97b644799 |
@@ -0,0 +1,154 @@
|
||||
# El
|
||||
|
||||
**A self-hosting, statically-typed language that compiles to C — built around a graph-native runtime instead of a database driver.**
|
||||
|
||||
El is the execution substrate for the Neuron agent runtime, the DHARMA network, and the Engram knowledge graph. This repository is the monorepo for the whole stack: the language itself, the graph memory engine it's built to talk to natively, and the tools (package manager, IDE, UI framework, diagramming) built on top of it.
|
||||
|
||||
---
|
||||
|
||||
## Why El exists
|
||||
|
||||
Every other language treats persistent, associative state as something you reach for through a driver — a SQL client, an ORM, a Redis library bolted on from outside. El inverts that: graph operations (`engram_*`) are runtime primitives, on the same footing as string or list operations. There is no separate database driver because the database is not separate.
|
||||
|
||||
El has four defining properties:
|
||||
|
||||
1. **Self-hosting compiler.** The compiler (`lexer.el`, `parser.el`, `codegen.el`, `compiler.el`) is written in El. It compiles El source to C, which `cc` compiles against a fixed runtime into a native binary. A Rust genesis compiler bootstrapped the first iteration; the self-hosted binary at `lang/dist/platform/elc` has been the canonical compiler ever since — every binary in `dist/platform/` was produced by an earlier version of itself compiling `el-compiler/src/`. The chain is auditable: source is the ground truth, not the binary. See [lang/BOOTSTRAP.md](lang/BOOTSTRAP.md) for the full recovery path if that binary is ever lost.
|
||||
2. **C compilation target.** Every compiled program is plain C11. Every El value is `el_val_t` (`int64_t`); strings are heap pointers cast through it. Functions become C functions; top-level statements become `main()`.
|
||||
3. **Graph-native runtime.** The runtime provides first-class graph operations over an in-process Engram store — no separate DB driver, no ORM.
|
||||
4. **DHARMA-aware identity.** A `cgi` block declares a program's DHARMA identity at compile time. The runtime resolves identity before user code runs, so `dharma_*` calls have a stable principal and channel surface throughout.
|
||||
|
||||
---
|
||||
|
||||
## Architecture map
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
│ lang │ El compiler + C runtime
|
||||
│ (El itself) │ everything below is written in it,
|
||||
└──────┬──────┘ or compiles down through it
|
||||
│
|
||||
┌─────────────┼─────────────┐
|
||||
│ │ │
|
||||
┌──────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
|
||||
│ engram │ │ epm │ │ ide │
|
||||
│ graph/mem │ │ package │ │ editor + │
|
||||
│ substrate │ │ manager │ │ LSP │
|
||||
└──────┬─────┘ └───────────┘ └───────────┘
|
||||
│
|
||||
┌───────┼────────────────┬─────────────────────┐
|
||||
│ │ │ │
|
||||
┌─────▼───┐ ┌─▼──────────┐ ┌──▼──────────┐ ┌─────▼──────┐
|
||||
│ elp │ │ ql │ │ ui │ │ arbor │
|
||||
│ NLG / │ │engram-el. │ |spreading- │ |arbor │
|
||||
│ 31 langs│ │studio+tests│ |activation UI│ |diagram lang│
|
||||
└─────────┘ └────────────┘ └─────────────┘ └────────────┘
|
||||
```
|
||||
|
||||
`lang` is the foundation — the compiler and C runtime everything else builds on. `engram` is the graph-native memory/state engine that gives El its identity (property 3 above). Everything else is either a tool for working with El (`epm`, `ide`) or a system built on top of Engram's graph model (`elp`, `ql`, `ui`, `arbor`).
|
||||
|
||||
---
|
||||
|
||||
## Repository layout
|
||||
|
||||
### [lang/](lang/) — the El language
|
||||
|
||||
The compiler and runtime. Self-hosting: `elc-cli.el` → `compiler.el` → `lexer.el` / `parser.el` / `codegen.el` / `codegen-js.el`, textually inlined and compiled in one pass. Compiles to C11 and links against `el-compiler/runtime/el_seed.c`, a hand-maintained OS-boundary layer (libcurl HTTP, pthreads, filesystem, arena allocation) — everything else in the runtime is native El (`runtime/*.el`).
|
||||
|
||||
Two layers to know: **El programs** (`.el` files — where nearly all work belongs) and **the C seed** (`el_seed.c` — edit only for genuine OS-level access; never re-implement what El can already express).
|
||||
|
||||
Current status (single source of truth: [lang/spec/language.md](lang/spec/language.md)): lexer/parser/codegen and the C runtime's core (I/O, strings, math, lists, maps, filesystem, args) are implemented. In flight: `%` operator, match-statement codegen, `?` nil-propagation, `cgi` block parsing + DHARMA identity resolution, VBD role enforcement (`@manager`/`@engine`/`@accessor`), the real `engram_*` and `dharma_*` runtimes (currently stubs), and libcurl-backed `http_get`/`http_post`/`http_serve`. Bitwise operators, `??`, and `as` casts are explicitly **not** in this language.
|
||||
|
||||
Key docs: [AGENTS.md](lang/AGENTS.md) (agent-facing orientation), [BOOTSTRAP.md](lang/BOOTSTRAP.md) (compiler recovery from scratch), [spec/language.md](lang/spec/language.md), [spec/codegen-js.md](lang/spec/codegen-js.md).
|
||||
|
||||
### [engram/](engram/) — graph intelligence substrate
|
||||
|
||||
**A local-first memory substrate for accumulating intelligence**, and the reason El's runtime doesn't need a database driver. Rust core (`engram-core`, `engram-ffi`) exposed to El and other languages (Kotlin, TypeScript/WASM, Go bindings).
|
||||
|
||||
The model: retrieval is **spreading activation**, not query. You name seed nodes and a query embedding; activation propagates outward through weighted edges, attenuating multiplicatively per hop (`strength = parent_strength × edge_weight × target_salience × cosine_sim`), gets pruned below a threshold, and the top-N nodes by activation strength come back. Storage and retrieval are the same structure — the way long-term potentiation works in biological memory, not the way a relational or vector database works.
|
||||
|
||||
Nodes live in four tiers (Working / Episodic / Semantic / Procedural, mirroring prefrontal / hippocampal / neocortical / cerebellar memory) and migrate between them based on **salience decay** — `importance × recency-decay × log(activation_count)`. Forgetting is adaptive pruning, not a bug: unreinforced memories stop competing for attention without being deleted.
|
||||
|
||||
Backed by `sled` (embedded, local-first, no daemon) with flat cosine scan for vector search — deliberately simple until scale demands an HNSW layer. Full API and design rationale in [engram/README.md](engram/README.md).
|
||||
|
||||
### [elp/](elp/) — Engram Language Protocol
|
||||
|
||||
Bidirectional engine mapping between Engram semantic forms and natural-language surface text, across **31 languages** — from Spanish and Japanese through historical/liturgical languages (Old Norse, Sanskrit, Sumerian, Coptic, Akkadian, Ge'ez). Compilation order runs `language-profile` + `vocabulary` → per-language `morphology-*` → `grammar` → `realizer` → `semantics` → `elp`. This is what lets an Engram graph node round-trip to and from readable text in any of those languages.
|
||||
|
||||
### [epm/](epm/) — El Package Manager
|
||||
|
||||
Manages **vessels** (El's package unit): publish, install, resolve dependencies. Vessels are stored in Engram as graph nodes, not files in a registry index — `epm` reads the local `manifest.el`, talks to Engram over HTTP, and writes resolved vessels to `.epm/vessels/`. Source: `registry.el`, `install.el`, `update.el`, `manifest.el`.
|
||||
|
||||
### [ide/](ide/) — El IDE
|
||||
|
||||
Three vessels: **el-ide-server** (HTTP backend — file ops, build/run, LSP bridge, plugin host, settings), **el-lsp** (the language server — completion, hover, diagnostics, outline, format, type graph), and **el-plugin-host** (first-party plugin lifecycle: install/remove/enable/disable). `ide/projects/` and `ide/examples/` hold sample projects, including the canonical `hello-friends` first-program walkthrough.
|
||||
|
||||
### [ql/](ql/) — engram-el
|
||||
|
||||
The El-native integration layer for a *live* Engram server — not a library (no importable modules, no build artifact), a set of standalone `.el` programs run directly via `el run-file`. Three components: **Studio** (`studio/studio.el`, a full terminal graph explorer), a **Hebbian field-model** proof of concept, and El builtin / LLM-builtin smoke test suites. This is the reference for correct patterns when an El program uses Engram as its substrate. Spec: [ql/spec/elql.md](ql/spec/elql.md).
|
||||
|
||||
### [ui/](ui/) — el-ui
|
||||
|
||||
A frontend framework where **component state is an Engram graph and reactivity is spreading activation** — not virtual-DOM diffing (React), Proxy-based dependency tracking (Vue), or compile-time analysis (Svelte). Re-renders are activated and propagated the same way associative memory retrieval works in `engram/`.
|
||||
|
||||
~15 vessels covering the full frontend surface: `el-platform` (env/fs/network/clock abstraction), `el-config`, `el-html` (SSR emit primitives), `el-layout`, `el-style` (design tokens/themes), `el-i18n`, `el-auth` / `el-identity` (JWT, sessions, OAuth PKCE — Engram-native), `el-services` (REST/gRPC/WebSocket bindings), `el-aop` (`@authenticate`/`@authorize`/`@cache`/`@rate_limit` decorators), `el-secrets`, `el-graph` (graph rendering/editor), `el-publish` (App Store / Play Store automation), and `el-ui-compiler` (El→JS component compiler; currently a stub pending a JS backend in `elc`). Spec: [ui/spec/framework.md](ui/spec/framework.md).
|
||||
|
||||
### [arbor/](arbor/) — diagram language
|
||||
|
||||
A `.arbor` diagram language and toolchain: `arbor-core` (NodeId/shape/edge-kind types), `arbor-parse` (recursive-descent parser), `arbor-diagram` (IR + Mermaid serializer + architecture-diagram builders), `arbor-layout` (hierarchical layout — rank assignment, positioning, group bounds), `arbor-render` (SVG renderer), `arbor-cli`. (The architecture map above is the kind of diagram this is for.)
|
||||
|
||||
---
|
||||
|
||||
## Getting started
|
||||
|
||||
Install the El SDK from the latest release:
|
||||
|
||||
```bash
|
||||
bash lang/install.sh
|
||||
# EL_VERSION=v1.0.0 bash lang/install.sh # pin a specific release tag
|
||||
# EL_PREFIX=/opt/el bash lang/install.sh # custom install prefix
|
||||
```
|
||||
|
||||
Or build the compiler from source and verify the self-hosting chain:
|
||||
|
||||
```bash
|
||||
cd lang
|
||||
./dist/platform/elc elc-cli.el > elc-new.c
|
||||
cc -std=c11 -I el-compiler/runtime -lcurl -lpthread \
|
||||
-o dist/platform/elc-new \
|
||||
elc-new.c el-compiler/runtime/el_seed.c
|
||||
|
||||
# Confirm the new binary reproduces itself exactly
|
||||
./dist/platform/elc-new elc-cli.el > elc-verify.c
|
||||
diff elc-new.c elc-verify.c # should be identical
|
||||
|
||||
mv dist/platform/elc-new dist/platform/elc
|
||||
```
|
||||
|
||||
Run your first program:
|
||||
|
||||
```bash
|
||||
./lang/dist/platform/elc lang/examples/hello.el > hello.c
|
||||
cc -std=c11 -I lang/el-compiler/runtime -lcurl -lpthread \
|
||||
-o hello hello.c lang/el-compiler/runtime/el_seed.c
|
||||
./hello
|
||||
```
|
||||
|
||||
More examples in [lang/examples/](lang/examples/), including a full starter project at `lang/examples/hello-project/`.
|
||||
|
||||
If the compiler binary is ever lost or corrupted, [lang/BOOTSTRAP.md](lang/BOOTSTRAP.md) is the authoritative recovery path.
|
||||
|
||||
---
|
||||
|
||||
## Development workflow
|
||||
|
||||
Branching follows `dev → stage → main`: work lands on `dev`, promotes to `stage` for integration testing, and is promoted to `main` for release (visible directly in the git history of this repo). CI is defined per-subproject under `.gitea/workflows/` — `lang`/`epm`/`ide` share the root pipeline; `engram` and `ql` carry their own (`ci-dev`, `ci-stage`, and a release workflow each).
|
||||
|
||||
- Language/runtime specs live at `*/spec/*.md` (`lang/spec/`, `ql/spec/`, `ui/spec/`) and are the single source of truth for implemented-vs-planned status — code and docs are expected to agree with the spec's status markers, not the other way around.
|
||||
- Agent-facing orientation guides live at `*/AGENTS.md` (currently `lang/AGENTS.md`); more subprojects may grow their own as they need agent-specific conventions documented.
|
||||
- Tagged releases live under `lang/releases/`, each with its own `RELEASE.md`.
|
||||
|
||||
---
|
||||
|
||||
## Status
|
||||
|
||||
This is an actively developed, internal monorepo — not yet published under an open license. Treat everything here as proprietary to Neuron Technologies unless told otherwise.
|
||||
Vendored
BIN
Binary file not shown.
@@ -5327,8 +5327,8 @@ el_val_t str_to_float(el_val_t s) {
|
||||
/* ── Math (Float-aware) ──────────────────────────────────────────────────── */
|
||||
|
||||
el_val_t math_sqrt(el_val_t f) { return el_from_float(sqrt(el_to_float(f))); }
|
||||
el_val_t math_log(el_val_t f) { return el_from_float(log10(el_to_float(f))); } /* base-10, per runtime/math.el */
|
||||
el_val_t math_ln(el_val_t f) { return el_from_float(log(el_to_float(f))); } /* natural log */
|
||||
el_val_t math_log(el_val_t f) { return el_from_float(log(el_to_float(f))); }
|
||||
el_val_t math_ln(el_val_t f) { return el_from_float(log(el_to_float(f))); }
|
||||
el_val_t math_sin(el_val_t f) { return el_from_float(sin(el_to_float(f))); }
|
||||
el_val_t math_cos(el_val_t f) { return el_from_float(cos(el_to_float(f))); }
|
||||
el_val_t math_pi(void) { return el_from_float(3.141592653589793238462643383279502884); }
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h> /* fmod, sin, sqrt, ... — used by codegen'd float arithmetic */
|
||||
|
||||
typedef int64_t el_val_t;
|
||||
|
||||
|
||||
@@ -731,41 +731,6 @@ fn cg_expr(expr: Map<String, Any>) -> String {
|
||||
// because both share the int64 slot).
|
||||
}
|
||||
|
||||
// -- Float arithmetic / comparison dispatch -------------------------
|
||||
// When either operand is provably Float, promote BOTH operands to a C
|
||||
// double and emit real double arithmetic. Arithmetic results are
|
||||
// re-wrapped into the el_val_t float slot via el_from_float(); the
|
||||
// integer % becomes fmod(); comparisons yield a bare 0/1. Without this
|
||||
// path, float `+` fell to el_str_concat (segfault) and `- * / %` fell
|
||||
// to integer ops on the raw IEEE-754 bit pattern (garbage). Mixed
|
||||
// Int/Float promotes the Int side with a (double) cast. This runs
|
||||
// AFTER temporal dispatch (a Float is never temporal) and BEFORE the
|
||||
// Int/String paths, and is skipped when either side is a bare Str so
|
||||
// string concat/equality is never disturbed.
|
||||
if !str_eq(left_kind, "Str") {
|
||||
if !str_eq(right_kind, "Str") {
|
||||
let any_float: Bool = false
|
||||
if is_float_expr(left) { let any_float = true }
|
||||
if is_float_expr(right) { let any_float = true }
|
||||
if any_float {
|
||||
let l_d: String = float_operand_c(left, left_c)
|
||||
let r_d: String = float_operand_c(right, right_c)
|
||||
if str_eq(op, "Plus") { return "el_from_float(" + l_d + " + " + r_d + ")" }
|
||||
if str_eq(op, "Minus") { return "el_from_float(" + l_d + " - " + r_d + ")" }
|
||||
if str_eq(op, "Star") { return "el_from_float(" + l_d + " * " + r_d + ")" }
|
||||
if str_eq(op, "Slash") { return "el_from_float(" + l_d + " / " + r_d + ")" }
|
||||
if str_eq(op, "Percent") { return "el_from_float(fmod(" + l_d + ", " + r_d + "))" }
|
||||
if str_eq(op, "Lt") { return "(" + l_d + " < " + r_d + ")" }
|
||||
if str_eq(op, "Gt") { return "(" + l_d + " > " + r_d + ")" }
|
||||
if str_eq(op, "LtEq") { return "(" + l_d + " <= " + r_d + ")" }
|
||||
if str_eq(op, "GtEq") { return "(" + l_d + " >= " + r_d + ")" }
|
||||
if str_eq(op, "EqEq") { return "(" + l_d + " == " + r_d + ")" }
|
||||
if str_eq(op, "NotEq") { return "(" + l_d + " != " + r_d + ")" }
|
||||
// And/Or with a float operand is ill-typed — fall through.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if op == "Plus" {
|
||||
// If either side is a string literal, always concat
|
||||
if left_kind == "Str" {
|
||||
@@ -1441,9 +1406,6 @@ fn cg_stmt(stmt: Map<String, Any>, indent: String, declared: [String]) -> [Strin
|
||||
if str_eq(ltype, "Int") {
|
||||
add_int_name(name)
|
||||
}
|
||||
if str_eq(ltype, "Float") {
|
||||
add_float_name(name)
|
||||
}
|
||||
// Temporal type annotations register the name with the matching
|
||||
// typed-set so BinOp / comparison codegen routes through the
|
||||
// typed wrappers and forbids cross-type ops.
|
||||
@@ -1503,12 +1465,6 @@ fn cg_stmt(stmt: Map<String, Any>, indent: String, declared: [String]) -> [Strin
|
||||
if is_zone_expr(val) {
|
||||
add_zone_name(name)
|
||||
}
|
||||
// Float inference: an unannotated `let` whose RHS is provably Float
|
||||
// (literal, math builtin, or float arithmetic) registers the name so
|
||||
// later `name <op> ...` routes through the double path.
|
||||
if is_float_expr(val) {
|
||||
add_float_name(name)
|
||||
}
|
||||
let vk: String = val["expr"]
|
||||
if str_eq(vk, "Int") {
|
||||
add_int_name(name)
|
||||
@@ -1828,15 +1784,6 @@ fn is_int_name(name: String) -> Bool {
|
||||
return str_contains(csv, "," + name + ",")
|
||||
}
|
||||
|
||||
// Float-typed binding set — parallel to is_int_name. Populated from `let x:
|
||||
// Float = ...` annotations, `: Float` parameters, and inference from a Float
|
||||
// RHS. Consulted by is_float_expr to route arithmetic through the double path.
|
||||
fn is_float_name(name: String) -> Bool {
|
||||
let csv: String = state_get("__float_names")
|
||||
if str_eq(csv, "") { return false }
|
||||
return str_contains(csv, "," + name + ",")
|
||||
}
|
||||
|
||||
// Same shape as is_int_name, for Instant- and Duration-typed bindings.
|
||||
// Used by the BinOp/comparison codegen to dispatch arithmetic through the
|
||||
// typed runtime wrappers (el_instant_add_dur, el_duration_lt, -) and to
|
||||
@@ -1900,28 +1847,6 @@ fn is_int_call(call_expr: Map<String, Any>) -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Known runtime builtins that return Float. Parallel to is_int_call — lets a
|
||||
// Call participate in float arithmetic (and get inferred into __float_names on
|
||||
// an unannotated `let`). New Float-returning builtins must be added here.
|
||||
fn is_float_call(call_expr: Map<String, Any>) -> Bool {
|
||||
let func = call_expr["func"]
|
||||
let fk: String = func["expr"]
|
||||
if !str_eq(fk, "Ident") { return false }
|
||||
let name: String = func["name"]
|
||||
if str_eq(name, "int_to_float") { return true }
|
||||
if str_eq(name, "str_to_float") { return true }
|
||||
if str_eq(name, "json_get_float") { return true }
|
||||
if str_eq(name, "decimal_round") { return true }
|
||||
if str_eq(name, "math_pi") { return true }
|
||||
if str_eq(name, "math_sin") { return true }
|
||||
if str_eq(name, "math_cos") { return true }
|
||||
if str_eq(name, "math_sqrt") { return true }
|
||||
if str_eq(name, "math_log") { return true }
|
||||
if str_eq(name, "math_ln") { return true }
|
||||
if str_eq(name, "el_from_float") { return true }
|
||||
return false
|
||||
}
|
||||
|
||||
// Builtins that return an Instant. Used by is_instant_expr and the BinOp
|
||||
// dispatch - `now() + 5.seconds` types as Instant only because we can see
|
||||
// that now() is an Instant-returning Call.
|
||||
@@ -2330,71 +2255,19 @@ fn is_int_expr(expr: Map<String, Any>) -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// is_float_expr — true when expr is (or provably evaluates to) a Float value.
|
||||
// Mirrors is_int_expr: Float literal, Neg of a Float, a Float-typed Ident
|
||||
// (registered in __float_names), a Float-returning builtin Call, or a Float
|
||||
// arithmetic BinOp (float propagates: if either operand is Float the result
|
||||
// is Float). Drives the float-arithmetic dispatch in cg_expr and the EqEq/
|
||||
// NotEq float comparison. Kept conservative (only provably-Float) so it never
|
||||
// intercepts a value the Int paths must own — the two predicates are mutually
|
||||
// exclusive on well-typed source.
|
||||
// is_float_expr — true when expr is (or evaluates to) a Float-typed value.
|
||||
// Used in EqEq/NotEq codegen to avoid str_eq on float values.
|
||||
fn is_float_expr(expr: Map<String, Any>) -> Bool {
|
||||
let k: String = expr["expr"]
|
||||
if str_eq(k, "Float") { return true }
|
||||
if str_eq(k, "Neg") {
|
||||
return is_float_expr(expr["inner"])
|
||||
}
|
||||
if str_eq(k, "Ident") {
|
||||
let name: String = expr["name"]
|
||||
return is_float_name(name)
|
||||
}
|
||||
if str_eq(k, "Call") {
|
||||
return is_float_call(expr)
|
||||
}
|
||||
if str_eq(k, "BinOp") {
|
||||
let op: String = expr["op"]
|
||||
if str_eq(op, "Plus") {
|
||||
if is_float_expr(expr["left"]) { return true }
|
||||
if is_float_expr(expr["right"]) { return true }
|
||||
return false
|
||||
}
|
||||
if str_eq(op, "Minus") {
|
||||
if is_float_expr(expr["left"]) { return true }
|
||||
if is_float_expr(expr["right"]) { return true }
|
||||
return false
|
||||
}
|
||||
if str_eq(op, "Star") {
|
||||
if is_float_expr(expr["left"]) { return true }
|
||||
if is_float_expr(expr["right"]) { return true }
|
||||
return false
|
||||
}
|
||||
if str_eq(op, "Slash") {
|
||||
if is_float_expr(expr["left"]) { return true }
|
||||
if is_float_expr(expr["right"]) { return true }
|
||||
return false
|
||||
}
|
||||
if str_eq(op, "Percent") {
|
||||
if is_float_expr(expr["left"]) { return true }
|
||||
if is_float_expr(expr["right"]) { return true }
|
||||
return false
|
||||
}
|
||||
return false
|
||||
let inner = expr["inner"]
|
||||
let ik: String = inner["expr"]
|
||||
if str_eq(ik, "Float") { return true }
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
// float_operand_c — render a BinOp operand as a C double for float arithmetic.
|
||||
// A provably-Float operand round-trips through el_to_float() (recovering the
|
||||
// double from the int64 bit-slot); anything else is treated as Int-like and
|
||||
// numerically converted with (double). This is why Float locals/params must
|
||||
// be annotated `: Float` — an unannotated var holding float bits would be
|
||||
// mis-converted by the (double) cast, exactly as the Int system requires
|
||||
// annotations to dispatch arithmetic vs concat.
|
||||
fn float_operand_c(expr: Map<String, Any>, expr_c: String) -> String {
|
||||
if is_float_expr(expr) { return "el_to_float(" + expr_c + ")" }
|
||||
return "(double)(" + expr_c + ")"
|
||||
}
|
||||
|
||||
// -- Capability-kind enforcement ----------------------------------------------
|
||||
//
|
||||
// A program's top-level block (cgi / service / none) determines which
|
||||
@@ -2911,15 +2784,6 @@ fn add_int_name(name: String) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
fn add_float_name(name: String) -> Bool {
|
||||
let csv: String = state_get("__float_names")
|
||||
if str_eq(csv, "") { csv = "," }
|
||||
let key: String = "," + name + ","
|
||||
if str_contains(csv, key) { return true }
|
||||
state_set("__float_names", csv + name + ",")
|
||||
return true
|
||||
}
|
||||
|
||||
fn add_instant_name(name: String) -> Bool {
|
||||
let csv: String = state_get("__instant_names")
|
||||
if str_eq(csv, "") { csv = "," }
|
||||
@@ -3003,7 +2867,6 @@ fn add_zone_name(name: String) -> Bool {
|
||||
|
||||
fn build_int_names_for_params(params: [Map<String, Any>]) -> Bool {
|
||||
state_set("__int_names", ",")
|
||||
state_set("__float_names", ",")
|
||||
state_set("__instant_names", ",")
|
||||
state_set("__duration_names", ",")
|
||||
state_set("__calendar_names", ",")
|
||||
@@ -3022,9 +2885,6 @@ fn build_int_names_for_params(params: [Map<String, Any>]) -> Bool {
|
||||
if str_eq(ptype, "Int") {
|
||||
add_int_name(pname)
|
||||
}
|
||||
if str_eq(ptype, "Float") {
|
||||
add_float_name(pname)
|
||||
}
|
||||
if str_eq(ptype, "Instant") {
|
||||
add_instant_name(pname)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user