ast (am baum)

This commit is contained in:
nora 2022-03-21 12:38:35 +01:00
parent c43fa694b8
commit 234f03dc1a
9 changed files with 457 additions and 0 deletions

10
ub_parser/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "ub_parser"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chumsky = "0.8.0"
logos = "0.12.0"

158
ub_parser/src/ast.rs Normal file
View file

@ -0,0 +1,158 @@
use crate::span::Span;
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq)]
pub struct File {
name: PathBuf,
items: Vec<Item>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Ty {
span: Span,
kind: TyKind,
}
#[derive(Debug, Clone, PartialEq)]
pub enum TyKind {
U64,
Ptr(Box<TyKind>),
Name(String),
}
#[derive(Debug, Clone, PartialEq)]
pub enum Item {
FnDecl(FnDecl),
StructDecl(StructDecl),
}
#[derive(Debug, Clone, PartialEq)]
pub struct FnDecl {
name: String,
params: Vec<FnParam>,
ret_ty: Ty,
span: Span,
body: Vec<Stmt>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct FnParam {
name: String,
ty: Ty,
span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct StructDecl {
name: String,
span: Span,
fields: Vec<StructField>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct StructField {
name: String,
ty: Ty,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Stmt {
VarDecl(VarDecl),
Assignment(Assignment),
IfStmt(IfStmt),
WhileStmt(WhileStmt),
LoopStmt(LoopStmt),
Item(Item),
Expr(Expr),
}
#[derive(Debug, Clone, PartialEq)]
pub struct VarDecl {
name: String,
ty: Ty,
rhs: Option<Expr>,
span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Assignment {
place: Place,
rhs: Expr,
span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct IfStmt {
cond: Expr,
body: Vec<Stmt>,
else_part: Option<ElsePart>,
span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ElsePart {
Else(Vec<Stmt>, Span),
ElseIf(Box<IfStmt>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct WhileStmt {
cond: Expr,
body: Vec<Stmt>,
span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct LoopStmt {
body: Vec<Stmt>,
span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
BinOp(BinOp),
Place(Place),
Call(Call),
Deref(Box<Expr>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct BinOp {
kind: BinOpKind,
lhs: Box<Expr>,
rhs: Box<Expr>,
span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum BinOpKind {
Add,
Sub,
Mul,
Div,
Mod,
Shr,
Shl,
And,
Or,
BitAnd,
BitOr,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Place {
FieldAccess(FieldAccess),
Name(String),
}
#[derive(Debug, Clone, PartialEq)]
pub struct FieldAccess {
expr: Box<Expr>,
field_name: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Call {
callee: Box<Expr>,
args: Vec<Expr>,
}

58
ub_parser/src/lexer.rs Normal file
View file

@ -0,0 +1,58 @@
use logos::Logos;
#[derive(Logos, Debug, PartialEq)]
pub enum Token {
// punctuation
#[token("{")]
BraceO,
#[token("}")]
BraceC,
#[token("[")]
BracketO,
#[token("]")]
BracketC,
#[token("(")]
ParenO,
#[token(")")]
ParenC,
#[token(".")]
Dot,
#[token("=")]
Eq,
#[token("==")]
EqEq,
#[token("!")]
Bang,
#[token("!=")]
BangEq,
#[token(">")]
Greater,
#[token("<")]
Less,
#[token(">=")]
GreaterEq,
#[token("<=")]
LessEq,
#[token("*")]
Asterisk,
#[token("/")]
Slash,
#[token("+")]
Plus,
#[token("-")]
Minus,
// keywords
#[token("struct")]
Struct,
#[token("fn")]
Fn,
#[error]
#[regex(r"[ \t\n\r\f]+")]
Error,
}
pub fn lex(code: &str) -> logos::Lexer<'_, Token> {
Token::lexer(code)
}

12
ub_parser/src/lib.rs Normal file
View file

@ -0,0 +1,12 @@
#![warn(rust_2018_idioms)]
#![allow(dead_code)]
use std::path::PathBuf;
mod ast;
mod lexer;
mod span;
pub fn parse(_str: &str, _file_name: PathBuf) -> Result<ast::File, ()> {
todo!()
}

5
ub_parser/src/span.rs Normal file
View file

@ -0,0 +1,5 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Span {
start: usize,
len: usize,
}