logos calculator example
This commit is contained in:
parent
d974798fcb
commit
0c30f0022d
9 changed files with 414 additions and 22 deletions
226
Cargo.lock
generated
226
Cargo.lock
generated
|
|
@ -2,22 +2,90 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "beef"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||
|
||||
[[package]]
|
||||
name = "chumsky"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14377e276b2c8300513dff55ba4cc4142b44e5d6de6d00eb5b2307d650bb4ec1"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"regex-automata",
|
||||
"serde",
|
||||
"stacker",
|
||||
"unicode-ident",
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lang"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chumsky",
|
||||
"logos",
|
||||
]
|
||||
|
||||
|
|
@ -27,6 +95,12 @@ version = "1.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.174"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "logos"
|
||||
version = "0.15.0"
|
||||
|
|
@ -47,7 +121,7 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex-syntax",
|
||||
"regex-syntax 0.8.5",
|
||||
"rustc_version",
|
||||
"syn",
|
||||
]
|
||||
|
|
@ -61,6 +135,12 @@ dependencies = [
|
|||
"logos-codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
|
|
@ -70,6 +150,15 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psm"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e944464ec8536cd1beb0bbfd96987eb5e3b72f2ecdafdc5c769a37f1fa2ae1f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
|
|
@ -79,6 +168,23 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax 0.7.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.5"
|
||||
|
|
@ -100,6 +206,45 @@ version = "1.0.26"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "stacker"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cddb07e32ddb770749da91081d8d0ac3a16f1a569a18b20348cd371f5dead06b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"psm",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.104"
|
||||
|
|
@ -116,3 +261,82 @@ name = "unicode-ident"
|
|||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ edition = "2024"
|
|||
|
||||
[dependencies]
|
||||
logos = "0.15.0"
|
||||
chumsky = "0.10.1"
|
||||
|
|
|
|||
18
src/ast/evaluator.rs
Normal file
18
src/ast/evaluator.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
use crate::ast::Expression;
|
||||
|
||||
|
||||
impl Expression {
|
||||
pub fn eval(&self) -> isize {
|
||||
match self {
|
||||
Expression::Integer(n) => *n,
|
||||
|
||||
|
||||
Expression::Negate(rhs) => -rhs.eval(),
|
||||
|
||||
Expression::Add(lhs, rhs) => lhs.eval() + rhs.eval(),
|
||||
Expression::Substract(lhs, rhs) => lhs.eval() - rhs.eval(),
|
||||
Expression::Multiply(lhs, rhs) => lhs.eval() * rhs.eval(),
|
||||
Expression::Divide(lhs, rhs) => lhs.eval() / rhs.eval(),
|
||||
}
|
||||
}
|
||||
}
|
||||
12
src/ast/mod.rs
Normal file
12
src/ast/mod.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
pub mod evaluator;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Expression {
|
||||
Integer(isize),
|
||||
Negate(Box<Expression>),
|
||||
// Binary operators,
|
||||
Add(Box<Expression>, Box<Expression>),
|
||||
Substract(Box<Expression>, Box<Expression>),
|
||||
Multiply(Box<Expression>, Box<Expression>),
|
||||
Divide(Box<Expression>, Box<Expression>),
|
||||
}
|
||||
16
src/lib.rs
16
src/lib.rs
|
|
@ -1,16 +0,0 @@
|
|||
mod lexer;
|
||||
|
||||
pub fn add(left: u64, right: u64) -> u64 {
|
||||
left + right
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
||||
36
src/main.rs
Normal file
36
src/main.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
use chumsky::Parser;
|
||||
use logos::Logos;
|
||||
|
||||
use crate::{parser::parser, tokens::Token};
|
||||
|
||||
mod tokens;
|
||||
mod ast;
|
||||
mod parser;
|
||||
|
||||
fn main() {
|
||||
let lexer = Token::lexer("(1 + 1) * 3");
|
||||
|
||||
let mut tokens = vec![];
|
||||
for (token, span) in lexer.spanned() {
|
||||
match token {
|
||||
Ok(token) => tokens.push(token),
|
||||
Err(e) => {
|
||||
println!("lexer error at {:?}: {:?}", span, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let ast = match parser().parse(&tokens).into_result() {
|
||||
Ok(expr) => {
|
||||
println!("[AST]\n{:#?}", expr);
|
||||
expr
|
||||
}
|
||||
Err(e) => {
|
||||
println!("parse error: {:#?}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("\n[result]\n{}", ast.eval());
|
||||
}
|
||||
56
src/parser.rs
Normal file
56
src/parser.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
use chumsky::{prelude::{just, recursive}, recursive, select, IterParser, Parser};
|
||||
|
||||
use crate::{ast::Expression, tokens::Token};
|
||||
|
||||
|
||||
#[allow(clippy::let_and_return)]
|
||||
/* ANCHOR: parser */
|
||||
pub fn parser<'src>(
|
||||
) -> impl Parser<'src, &'src [Token<'src>], Expression, chumsky::extra::Err<chumsky::error::Simple<'src, Token<'src>>>>
|
||||
{
|
||||
recursive(
|
||||
|p|
|
||||
{
|
||||
let atom = {
|
||||
let parenthesized = p
|
||||
.clone()
|
||||
.delimited_by(just(Token::ParenBegin), just(Token::ParenEnd));
|
||||
|
||||
let integer = select! {
|
||||
Token::Integer(n) => Expression::Integer(n),
|
||||
};
|
||||
|
||||
parenthesized.or(integer)
|
||||
};
|
||||
|
||||
let unary = just(Token::Substract)
|
||||
.repeated()
|
||||
.foldr(atom, |_op, rhs| Expression::Negate(Box::new(rhs)));
|
||||
|
||||
let binary_1 = unary.clone().foldl(
|
||||
just(Token::Multiply)
|
||||
.or(just(Token::Divide))
|
||||
.then(unary)
|
||||
.repeated(),
|
||||
|lhs, (op, rhs)| match op {
|
||||
Token::Multiply => Expression::Multiply(Box::new(lhs), Box::new(rhs)),
|
||||
Token::Divide => Expression::Divide(Box::new(lhs), Box::new(rhs)),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
);
|
||||
|
||||
let binary_2 = binary_1.clone().foldl(
|
||||
just(Token::Add)
|
||||
.or(just(Token::Substract))
|
||||
.then(binary_1)
|
||||
.repeated(),
|
||||
|lhs, (op, rhs)| match op {
|
||||
Token::Add => Expression::Add(Box::new(lhs), Box::new(rhs)),
|
||||
Token::Substract => Expression::Substract(Box::new(lhs), Box::new(rhs)),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
);
|
||||
|
||||
binary_2
|
||||
})
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ use logos::{Lexer, Logos};
|
|||
|
||||
#[derive(Logos, Debug, Clone, PartialEq)]
|
||||
#[logos(skip r"[ \t\r\n\f]+")] // Skips whitespace
|
||||
enum Token<'source> {
|
||||
pub enum Token<'source> {
|
||||
#[token("false", |_| false)]
|
||||
#[token("true", |_| true)]
|
||||
Bool(bool),
|
||||
|
|
@ -18,16 +18,40 @@ enum Token<'source> {
|
|||
|
||||
#[token("/")]
|
||||
Divide,
|
||||
|
||||
#[token("=")]
|
||||
Equals,
|
||||
|
||||
#[token(":")]
|
||||
Colon,
|
||||
|
||||
#[token("(")]
|
||||
ParenBegin,
|
||||
|
||||
#[token(")")]
|
||||
ParenEnd,
|
||||
|
||||
#[token("{")]
|
||||
BraceBegin,
|
||||
|
||||
#[token("}")]
|
||||
BraceEnd,
|
||||
|
||||
#[regex("[0-9]+", |lex| lex.slice().parse::<isize>().unwrap())]
|
||||
Integer(isize),
|
||||
|
||||
#[regex(r"[_a-zA-Z][_0-9a-zA-Z]*")]
|
||||
Ident(&'source str),
|
||||
|
||||
#[regex(r#""([^"\\\x00-\x1F]|\\(["\\bnfrt/]|u[a-fA-F0-9]{4}))*""#, |lex| lex.slice().to_owned())]
|
||||
String(String),
|
||||
}
|
||||
|
||||
fn float<'a>(lex: &mut Lexer<'a, Token<'a>>) -> Result<f64, ()> {
|
||||
lex.slice().parse().map_err(|_| ())
|
||||
#[token("class")]
|
||||
#[token("fun")]
|
||||
#[token("var")]
|
||||
#[token("if")]
|
||||
#[token("else")]
|
||||
Keyword(&'source str),
|
||||
}
|
||||
|
||||
|
||||
39
syntax.akai
39
syntax.akai
|
|
@ -1,3 +1,20 @@
|
|||
class Position:
|
||||
// Properties
|
||||
var int: x
|
||||
var int: y
|
||||
|
||||
// Constructor
|
||||
Position(_x, _y) {
|
||||
x = _x
|
||||
y = _y
|
||||
}
|
||||
|
||||
// Inheritance
|
||||
class Cat derive Animal:
|
||||
/*
|
||||
code goes here
|
||||
*/
|
||||
|
||||
fun helloWorld() {
|
||||
// Variables either dynamically or statically typed
|
||||
var String: test = "I'm a string"
|
||||
|
|
@ -6,4 +23,24 @@ fun helloWorld() {
|
|||
var bar = foo + 10
|
||||
|
||||
print("Hello World " + bar)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Keywords/ Tokens:
|
||||
- class
|
||||
- fun
|
||||
- var
|
||||
- bool
|
||||
- if
|
||||
- else
|
||||
- (
|
||||
- )
|
||||
- {
|
||||
- }
|
||||
- :
|
||||
- +
|
||||
- -
|
||||
- /
|
||||
- *
|
||||
- =
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue