Skip to content

Implement Phase 2 (atom types) and Phase 4 (Elbo compiler) from feature plan#9

Merged
drzo merged 5 commits into
masterfrom
copilot/implement-plan
Jun 8, 2026
Merged

Implement Phase 2 (atom types) and Phase 4 (Elbo compiler) from feature plan#9
drzo merged 5 commits into
masterfrom
copilot/implement-plan

Conversation

Copilot AI commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Implements high-priority items from the CogDiod Exhaustive Feature Implementation Plan.

Phase 2 — New Atom Types

7 new package stubs following the existing elm_build_stub() pattern:

  • ExecutionLink — triggers GroundedSchemaNode.execute() on MSG_INFER
  • ContextLink — scoped evaluation context
  • PredictiveImplicationLink — temporal implication with OP_PLN_TMP decay
  • AtTimeLink / TimeNode — event-at-timestamp primitives
  • GroundedSchemaNode / GroundedPredicateNode — callable atoms with function pointers

Phase 4 — Elbo Compiler Completeness

Extended the S-expression → Dis bytecode compiler:

Feature Implementation
Conditionals if/cond/when/unless with JEQ/JNE + backpatching
Bindings let/define forms
Lambdas fn/defun/lambda with OP_CALL/OP_RET frames
Float literals is_number() + strtof() with ERANGE handling
File compilation elbo_compile_file() for .elbo → .elm
// New API
int elbo_compile_file(const char* src_path, const char* out_path);

// Example Elbo source now supported
(if (> x 0)
    (send result "positive")
    (send result "non-positive"))

(let ((a 3.14) (b 2.71))
    (+ a b))

Bug Fixes

  • Added elm_load_file declaration to elm_types.h — implicit declaration was truncating 64-bit pointer to int causing segfaults
  • Fixed infinite loop in unknown form parsing — now properly skips nested sub-expressions

Other Changes

  • Added ELBO_MAX_COND_CLAUSES (64) with bounds checking
  • Added ELBO_MAX_SOURCE_SIZE (1MB) constant
  • Proper error handling for strtof(), malloc, and fread

Note

Medium Risk
Large compiler/parser changes and new inference/execution atom stubs affect core VM bytecode paths; elm_load_file declaration fixes a prior segfault but loader usage remains sensitive.

Overview
Adds seven new atom-type Elm stub packages (execution, context, predictive implication, at-time/time, grounded schema/predicate) and wires them into the Makefile build.

Extends the Elbo compiler with conditionals (if/cond/when/unless + jump backpatching), binding stubs (let/define), lambda-style forms (fn/lambda/defun), float literals via OP_LOAD, and elbo-module. Unknown forms now compile nested expressions instead of looping. Adds elbo_compile_file (.elbo → .elm, CamelCase type name from basename, 1MB cap) and declares elm_load_file in elm_types.h for correct 64-bit pointer typing.

Reviewed by Cursor Bugbot for commit d0e125f. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI assigned Copilot and drzo Jun 8, 2026
Copilot AI linked an issue Jun 8, 2026 that may be closed by this pull request
Copilot AI added 4 commits June 8, 2026 13:38
…ments)

Phase 2 — New Atom Types:
- ExecutionLink: triggers GroundedSchemaNode execution
- ContextLink: scoped evaluation context
- PredictiveImplicationLink: temporal implication with decay
- AtTimeLink: event at specific timestamp
- TimeNode: stores timestamp value
- GroundedSchemaNode: callable atom with function pointer
- GroundedPredicateNode: callable predicate evaluation

Phase 4 — Elbo Compiler Completeness:
- 4.1: let/define forms for variable bindings
- 4.2: Conditionals (if/cond/when/unless) with JEQ/JNE opcodes
- 4.4: Lambda/defun/fn forms with call-return frames
- 4.5: Float literal parsing and LOAD opcode emission
- 4.6: elbo_compile_file() for .elbo → .elm compilation

Also:
- Added elm_load_file declaration to elm_types.h
- Fixed unknown form handling to skip nested expressions
- Added elbo-module form support
- Fix cond form to properly compile test expressions instead of emitting OP_NOP
- Add ELBO_MAX_COND_CLAUSES constant (64) with bounds checking and warning
- Use strtof() instead of strtod() to avoid double→float precision loss
- Add ELBO_MAX_SOURCE_SIZE constant (1MB) for file size limit
- Use toupper() instead of magic number -32 for case conversion
- Add errno checking for strtof() with endptr validation
- Fix cond clause overflow to break loop and skip remaining clauses
- Add errno.h include
- Better strtof() error handling: check endptr first, then ERANGE
- Add diagnostic message for malloc failure
- Check for short reads in elbo_compile_file
Copilot AI changed the title [WIP] Implement the plan for CogDiod exhaustive feature implementation Implement Phase 2 (atom types) and Phase 4 (Elbo compiler) from feature plan Jun 8, 2026
Copilot AI requested a review from drzo June 8, 2026 13:45
Copilot finished work on behalf of drzo June 8, 2026 13:45

@drzo drzo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coool

@drzo drzo marked this pull request as ready for review June 8, 2026 14:25
@drzo drzo merged commit 721a230 into master Jun 8, 2026
7 checks passed

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 5 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d0e125f. Configure here.

Comment thread src/elbo/elbo_compiler.c
/* f will be HUGE_VALF or 0.0, use it anyway */
}
bb_emit(b, OP_LOAD);
bb_emit_float(b, f);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Float literals misalign bytecode

High Severity

The compiler emits OP_LOAD followed by a 4-byte float for number literals. However, the Dis VM's OP_LOAD instruction doesn't expect an immediate operand. This causes the float's bytes to be incorrectly executed as instructions, corrupting program flow.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d0e125f. Configure here.

Comment thread src/elbo/elbo_compiler.c
* Compile: test → JEQ else_label → then → JMP end_label → else → end
*/
compile_expr(l, b); /* compile test */
bb_emit(b, OP_JEQ); /* jump if false (regs[0] == 0) */

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conditional jumps compare two registers

High Severity

The compiler's conditional forms (if, when, unless, cond) emit OP_JEQ/OP_JNE opcodes. The VM's branching logic for these opcodes compares regs[0] against regs[1], but the compiler only populates regs[0] with the test expression's result. This leaves regs[1] uninitialized, causing conditional branches to rely on arbitrary register state instead of the intended test outcome.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d0e125f. Configure here.

Comment thread src/elbo/elbo_compiler.c
lex_atom(l, varname, sizeof(varname));
(void)varname;
compile_expr(l, b);
bb_emit(b, OP_STORE);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bindings store without heap address

Medium Severity

The let and define forms compile to OP_STORE but ignore binding names and don't set a distinct heap address in regs[1]. This means variables lack unique storage, potentially overwriting each other or writing to an invalid location.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d0e125f. Configure here.

Comment thread src/elbo/elbo_compiler.c
} else {
/* Symbol - emit NOP for now (would be a LOAD from symbol table) */
bb_emit(b, OP_NOP);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File compile truncates embedded NUL

Medium Severity

elbo_compile_file reads the full file with fread, but elbo_compile initializes the lexer length with strlen(source). Any NUL byte inside the buffer ends parsing there, so the rest of the file is silently dropped without an error.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d0e125f. Configure here.

Comment thread src/elbo/elbo_compiler.c
break;
}

bb_patch_u64(b, next_clause, bb_offset(b));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cond overflow leaves jump holes

Medium Severity

When a cond has more than ELBO_MAX_COND_CLAUSES branches, the compiler logs an error and breaks out of parsing but skips bb_patch_u64 for the current clause’s OP_JEQ placeholder. That leaves a zero jump target in the bytecode while earlier clauses may still be patched, producing unpredictable control flow.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d0e125f. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

implemet plan

2 participants