Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/l1mey112/jitcalc

jitcalc is a calculator written in the V programming language that evaluates expressions by creating x86_64 programs at runtime.
https://github.com/l1mey112/jitcalc

assembly calculator cli jit vlang x86-64

Last synced: 24 days ago
JSON representation

jitcalc is a calculator written in the V programming language that evaluates expressions by creating x86_64 programs at runtime.

Awesome Lists containing this project

README

        

# `jitcalc`

![](.assets/image.png)

### `jitcalc` is a calculator written in the V programming language.

What's special about it?

After parsing the input expression and generating a syntax tree, it does something different. Instead of traversing the tree interpreting the final solution, it creates a x86_64 program just in time and executes it, generating the answer.

After each line a hexdump and x86_64 assembly instructions are listed on the left. Use the `ast` command to toggle dumping the expression's AST alongside it.

Variables can be declared and assigned, and are preserved between expressions. Use the `reset` command to reset the symbol table.

### [Want to read more? Check out the article on `l-m.dev` here!](https://l-m.dev/cs/jitcalc/)

# code

![](.assets/node.png)

Constituting for about 93 lines of the program, code generation is incredibly simple. By calling the `gen()` function recursively over an entire expression tree, machine code can be generated.

```v
type Symtable = map[string]&Box[i64]

fn gen(node &Expr, mut prg JitProgram, mut symtable Symtable)!
```

About 64 lines, parsing is just as simple. Using a recursive pratt parser it can generate a syntax tree.

```v
struct Expr {
lhs &Expr = unsafe { nil }
rhs &Expr = unsafe { nil }
op Op
val string
}

fn expr(mut l Lexer, min_bp int) !&Expr
```

49 lines, the lexer is efficient. It has the ability to look ahead by one token and is called by the parser constantly requesting tokens.

```v
enum Op { eof uneg ident assign obr cbr num add sub mul div mod }

struct Lexer {
line string
mut:
pos int
tok Op
tok_lit string
peek Op
peek_lit string
}

fn (mut l Lexer) next() !Op
```