• Stars
    star
    118
  • Rank 290,532 (Top 6 %)
  • Language
    Rust
  • License
    MIT License
  • Created about 1 year ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Build Abstract Syntax Trees and tree-walking models quickly in Rust.

astmaker

Crates.io Crates.io Crates.io docs.rs

Build Abstract Syntax Trees and tree-walking models quickly in Rust.

Example

This example creates an AST for simple math expressions, and an interpreter to evaluate the result:

use astmaker::{ast, model};

#[derive(Debug, Clone, PartialEq)]
pub enum BinOp {
  Add,
  Sub,
  Mul,
  Div,
}

#[derive(Debug, Clone, PartialEq)]
pub enum UnOp {
  Add,
  Sub,
}

ast!{
  location = ();

  pub node Expression =
    | BinOp -> Node<BinaryOperation>
    | UnOp -> Node<UnaryOperation>
    | Num -> Node<Number>
    ;

  pub node BinaryOperation = {
    lhs: Node<Expression>,
    op: BinOp,
    rhs: Node<Expression>,
  }

  pub node UnaryOperation = {
    op: UnOp,
    expr: Node<Expression>,
  }

  pub node Number = {
    value: f64,
  }
}

pub struct Interpreter;

model!{
  impl Interpreter -> f64 {
    where Expression => {
      match node.data.as_mut() {
        Expression::BinOp(child_node) => context.visit(child_node),
        Expression::UnOp(child_node) => context.visit(child_node),
        Expression::Num(child_node) => context.visit(child_node),
      }
    },
    where BinaryOperation => {
      let lhs = context.visit(&mut node.data.lhs);
      let rhs = context.visit(&mut node.data.rhs);

      match node.data.op {
        BinOp::Add => lhs + rhs,
        BinOp::Sub => lhs - rhs,
        BinOp::Mul => lhs * rhs,
        BinOp::Div => lhs / rhs,
      }
    },
    where UnaryOperation => {
      let val = context.visit(&mut node.data.expr);

      match node.data.op {
        UnOp::Add => val,
        UnOp::Sub => -val,
      }
    },
    where Number => node.data.value,
  }
}

#[test]
fn eval() {
  let mut tree = Node::new((), Expression::BinOp(
    Node::new((), BinaryOperation {
      lhs: Node::new((), Expression::Num(
        Node::new((), Number { value: 1.0 })
      )),
      op: BinOp::Add,
      rhs: Node::new((), Expression::Num(
        Node::new((), Number { value: 2.0 })
      ))
    })
  ));

  let mut interpreter = Interpreter;

  assert_eq!(interpreter.visit(&mut tree), 3.0);
}

Roadmap

  • πŸ“ Documentation
  • ✨ Generics support
  • ✨ Lifetimes support
  • πŸ‘· Github workflows to build, test & publish crate

License

This project is released under the terms of the MIT License.

More Repositories

1

aitoolkit

Give a brain to your game's NPCs
C++
440
star
2

letlang

Functional language with a powerful type system.
Rust
157
star
3

shipp

Deadly simple package manager
Rust
94
star
4

sdl-game-engine

2D game engine based on SDL2
C++
91
star
5

logfmtxx

Header only C++23 structured logging library using logfmt
C++
68
star
6

tricorder

Automation the KISS way
Rust
50
star
7

doceaser

Interactive documentation with Markdown and HTMX made easier
Python
37
star
8

triotp

TriOTP, the OTP framework for Python Trio
Python
35
star
9

lispers

Educational project: How to implement a Lisp interpreter in Rust?
Rust
32
star
10

tshellout

Typescript Shell Out library, to simplify writing and composing shell commands for NodeJS
TypeScript
24
star
11

rustic_result

Result monad for Elixir inspired by Rust Result type
Elixir
21
star
12

elixir-k8s-love-story

Repository for the Medium series "Elixir and Kubernetes: A love story"
Elixir
20
star
13

easymd

Simple HTTP server to render markdown documents
Go
9
star
14

ooduck

Duck-Typing C library based on ooc.pdf
C
9
star
15

cream-browser

Web browser developped in C with GTK+ (same interface as Vimperator)
C
9
star
16

procfusion

Very simple process manager written in Rust for your Docker images
Rust
8
star
17

slightx

A free x86 operating system conforming to POSIX.
C
7
star
18

lemonldap-cli

Command Line tool to configure LemonLDAP::NG (depecrated: now maintained by the LemonLDAP::NG team)
Perl
7
star
19

link.crdt

Python implementation of Convergent Replicated Data Types
Python
7
star
20

airscript

Like Lua, but in Rust, and different
Rust
6
star
21

plstblog

Staitc blog generator written in Perl
Perl
6
star
22

fwallsh

Command line interface to configure your Linux router/server.
C
5
star
23

secure-user-data

Infrastructure to store, manage and access user data in a very secure manner.
Python
4
star
24

microci

MicroCI for lightweight self hosted continuous integration
Python
4
star
25

gin

Opinionated static website generator
TypeScript
3
star
26

graphbase

Graph oriented database
Erlang
3
star
27

manyssh

One command line to control multiple SSH connections.
Python
3
star
28

pcstats

Affiche les infos CPU/RAM/Disk du PC, dispo uniquement sous Linux
C
3
star
29

greenpkg

Little package manager inspired of Gentoo and BSD
C
2
star
30

yavm

Yet Another Virtual Machine
C
2
star
31

kickle-clone

Clone of the NES game "Kickle Cubicle"
C++
2
star
32

knowledgebase

Knowledge database organized in graph
JavaScript
2
star
33

rustic_maybe

Maybe monad for Elixir inspired by Rust Option type
Elixir
1
star
34

link.kvstore

Key/Value store generic API
Python
1
star
35

arecursion-js

Asynchronous recursion without maximum depth
JavaScript
1
star
36

hftforge

Forge in Python/Django
1
star
37

link.graph

Pure-Python graph database
Python
1
star
38

linkdd.github.io

linkdd's pages
HTML
1
star
39

link.wsgi

Fully configurable WSGI microframework
Python
1
star
40

wmfs-fifo

FIFO for WMFS2
C
1
star
41

linkdd-overlay

My own gentoo overlay
Shell
1
star
42

dirwatcher

Directory watcher for livereloading scripts
Python
1
star
43

xautostart

Python script to run all desktop entries in autostart directories
Python
1
star
44

notebook

Static Markdown Renderer
HTML
1
star
45

link.fulltext

Middleware feature for generic Fulltext-Index manipulation
Python
1
star
46

i3tools

Tools for i3wm
Python
1
star
47

9cal

CalDav server which respects the RFC
Python
1
star