- Add a variant to
TokenKindinsrc/lexer.rs - Add a match arm in the
keyword()function insrc/lexer.rs - Add the corresponding AST node(s) to
src/ast.rsif needed - Add a
parse_*method in the appropriatesrc/parser/*.rssubmodule and call it fromparse_top_level()insrc/parser/module.rs - Add a handler in the VM compiler (
src/vm/compiler.rs) to emit the appropriate opcodes
Concrete example — adding maintain (goal-based looping):
Aver has no for/while. Future iteration uses goal-based constructs. Here is the extension pattern for a maintain keyword:
// lexer.rs — add:
Maintain,
// keyword() — add:
"maintain" => Some(TokenKind::Maintain),
// ast.rs — add to Expr:
Maintain(Box<Expr>, Box<Expr>), // condition, body block
// parser/expr.rs — add method:
fn parse_maintain(&mut self) -> Result<Expr, ParseError> {
self.expect_exact(&TokenKind::Maintain)?;
let cond = self.parse_expr()?;
self.expect_exact(&TokenKind::Colon)?;
// parse indented body block
}
// vm/compiler.rs — add to compile_expr():
// Emit opcodes for maintain: compile condition, emit conditional jump,
// compile body, emit jump back to condition check
All functions live in namespaces (e.g., Int.abs, List.len, Console.print). To add a new function to an existing namespace:
- Add the implementation in the namespace's file (e.g.,
src/types/int.rsfor pure,src/services/console.rsfor effectful) insidecall():"Int.yourMethod" => { // validate args, return Ok(Value::...) }
- Register the member name in
register()so it appears in the namespace'smembersmap. - Add the type signature in
src/types/checker/builtins.rsin the corresponding sigs section.
To create a new pure namespace, follow the pattern in src/types/char.rs or src/types/int.rs: implement register(), effects(), and call(), add pub mod in src/types/mod.rs, wire dispatch in src/vm/runtime.rs. For effectful namespaces, use src/services/ instead.
- Add a variant to
Exprinsrc/ast.rs - Parse it in
src/parser/expr.rs(typically inparse_atomor a new precedence level) - Compile it in
src/vm/compiler.rsto emit the appropriate opcodes - If it should appear in verify cases, update
expr_to_strinsrc/checker.rs