Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Finch Cheatsheet

Quick reference derived from the current parser/interpreter (chumsky-based).

Comments

// line comment
/* block
   comment */

Variables

var x = 10;
var name = "hi";
x = x + 1;        // assignment to an *already declared* var
  • Assigning to an undeclared name is an error (UndeclaredAssign).
  • var re-declares/shadows in the current scope (each { } block gets a child Environment).

Types

Type Literal Notes
Num 10, 3.14 f64 under the hood, digits + optional .digits
Str "text" no escape sequences supported yet
Bool (no literal syntax) only produced by comparisons/logic — no true/false keyword in the grammar
Fn via fn decl closures capture their defining Environment

Truthiness (is_truthy):

  • Bool → itself
  • Numfalse only if 0.0
  • Strfalse only if empty
  • Fn → always true

Operators

+  -  *  /          // arithmetic (Div by zero is an error)
== != < > <= >=      // comparison
&&  ||               // logical (short-circuit)
!expr                // logical not
-expr                // unary negation (desugars to 0 - expr)
  • + also does string concatenation: if either side is a Str, the result is a Str (numbers get Display-formatted in).
  • No % modulo, no bitwise ops, no +=/-= etc.

Print

print "hello";
print 1 + 2;

Control flow

if (cond) {
    ...
} elif (cond) {
    ...
} else {
    ...
}

while (cond) {
    ...
}

for (var i = 0; i < 10; i = i + 1) {
    ...
}
  • for's init/cond/post are all optional (for (;;) { ... } is valid).
  • elif desugars to a nested if in the else branch.

Functions

fn add(a, b) {
    return a + b;
}

add(1, 2);
  • return; and return expr; both valid; a function that falls off the end (or does bare return;) yields Num(0.0) as its call-expression value.
  • Functions are first-class Value::Fn — stored in variables, called via name(args). Arg count mismatches error out (ArgCountMismatch).
  • Closures capture the environment they were declared in (Rc<RefCell<Environment>>), so nested/returned functions retain access to outer scope.

Imports / stdlib

import <math>;
import <string>;
import <mvis>;
  • Importing pulls that module's native functions into the flat ctx.functions call namespace (no mod.fn() syntax — just fn() after import, even though the names are prefixed math_/str_).
  • Unknown import name → EvalError::UnknownImport.
  • Known gap: KNOWN_MODULES (interpreter side) currently only contains "mvis". math and string are registered via register_stdlib/register_module_fn but import <math>; / import <string>; will fail with UnknownImport until KNOWN_MODULES is updated (or the check is changed to look at ctx.stdlib.contains_key instead of the hard-coded list) — this is presumably what PATCH_NOTES.md refers to as still-pending interpreter-side work.

math module

Function Signature Notes
math_abs(x) num → num
math_sqrt(x) num → num errors if x < 0
math_pow(base, exp) num, num → num
math_floor(x) / math_ceil(x) / math_round(x) / math_trunc(x) num → num
math_min(a, b) / math_max(a, b) num, num → num 2-arg only, no varargs
math_pi() → num takes no args, still called as math_pi()
math_log(x) num → num natural log; errors if x <= 0
math_log2(x) / math_log10(x) num → num errors if x <= 0
math_exp(x) num → num
math_sin(x) / math_cos(x) / math_tan(x) num → num radians
math_asin(x) / math_acos(x) num → num errors if x outside [-1, 1]
math_atan(x) num → num
math_atan2(y, x) num, num → num
math_sign(x) num → num 1, -1, or 0
math_clamp(x, min, max) num, num, num → num errors if min > max
math_random() → num in [0, 1); simple xorshift seeded off system time — not cryptographically random

string module

Function Signature Notes
str_len(s) str → num char count, not bytes
str_upper(s) / str_lower(s) str → str
str_trim(s) str → str
str_contains(s, sub) str, str → bool
str_replace(s, from, to) str, str, str → str replaces all occurrences
str_index_of(s, sub) str, str → num char index, -1 if not found (converts from byte index internally)
str_substr(s, start, len) str, num, num → str char-based; errors if start/len negative
str_to_num(s) str → num errors if not parseable as f64
str_from_num(x) num → str

All stdlib errors surface as EvalError::Native(String) with a "fn_name: message" format, and arity mismatches use the same ArgCountMismatch as user-defined functions.

Host integration (Rust side, not Finch syntax)

let mut interp = Interpreter::new();
interp.set_var("x", Value::Num(5.0));
interp.register_fn("double", |args| { /* ... */ Ok(Value::Num(args[0].as_num()? * 2.0)) });
interp.register_module_fn("mvis", "snapshot", |args| { /* ... */ });
interp.eval_str("print double(x);")?;
// or
interp.eval_file("script.finch")?;

Known gaps / things to watch for

  • No true/false/nil literals in the grammar — only reachable as values through comparisons or return defaults.
  • No string escaping (\", \n, etc.) — none_of('"') reads until the next literal ".
  • No arrays/lists/objects yet.
  • No % or compound assignment operators.
  • Step/recursion limits exist in EvalError (StepLimitExceeded) but aren't wired into the eval loop shown here yet.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages