add break to lex and create first ast

This commit is contained in:
nora 2021-10-20 19:57:25 +02:00
parent 40a7aaac71
commit 186eb71a50
4 changed files with 110 additions and 2 deletions

View file

@ -125,6 +125,7 @@ _ is dynamically and *strongly* typed
`loop`
`while`
`for`
`break`
#### Values
`true`

101
src/ast.rs Normal file
View file

@ -0,0 +1,101 @@
pub struct Block(pub Vec<Stmt>);
pub enum Stmt {
VariableDecl(VariableDecl),
Assignment(Assignment),
FnDecl(FnDecl),
Break,
Return(Option<Expr>),
Conditional(Conditional),
Loop(Block),
WhileLoop(WhileLoop),
ForLoop(Box<ForLoop>),
Expr(Expr),
}
pub struct VariableDecl {
name: String,
init: Option<Expr>,
}
pub struct Assignment {
pub lhs: Expr,
pub rhs: Expr,
}
pub struct FnDecl {
pub name: String,
pub params: Vec<String>,
pub body: Block,
}
pub struct Conditional {
pub condition: Expr,
pub body: Block,
pub else_block: Option<Block>,
}
pub struct WhileLoop {
pub cond: Expr,
pub body: Block,
}
pub struct ForLoop {
pub init: Stmt,
pub cond: Expr,
pub post: Stmt,
pub body: Block,
}
pub enum Expr {
Literal(Literal),
UnaryOp,
BinaryOp,
Call,
}
pub enum Literal {
String(String),
Number(f64),
Array(Vec<Expr>),
Object, // todo
Boolean(bool),
Null,
}
pub struct UnaryOp {
pub expr: Expr,
pub kind: UnaryOpKind,
}
pub enum UnaryOpKind {
Not,
Neg,
}
pub struct BinaryOp {
pub lhs: Expr,
pub rhs: Expr,
pub kind: BinaryOpKind,
}
pub enum BinaryOpKind {
And,
Or,
Equal,
GreaterEqual,
Greater,
LessEqual,
Less,
NotEqual,
Add,
Sub,
Mul,
Div,
Mod,
}
pub enum Call {
Function(Expr, Vec<Expr>),
Field(Expr, Vec<Expr>),
}

View file

@ -35,6 +35,7 @@ pub enum TokenType<'code> {
Loop,
While,
For,
Break,
True,
False,
Null,
@ -322,6 +323,8 @@ fn keyword_or_ident(name: &str) -> TokenType {
b'e' if len == 4 && bs[1..4] == *b"lse" => TokenType::Else,
// while
b'w' if len == 5 && bs[1..5] == *b"hile" => TokenType::While,
// break
b'b' if len == 5 && bs[1..5] == *b"reak" => TokenType::Break,
// true
b't' if len == 4 && bs[1..4] == *b"rue" => TokenType::True,
// null && not
@ -568,9 +571,9 @@ mod test {
#[test]
fn keywords() {
lex_test(
"let fn if else loop while for true false null and not or",
"let fn if else loop while break for true false null and not or",
vec![
Let, Fn, If, Else, Loop, While, For, True, False, Null, And, Not, Or,
Let, Fn, If, Else, Loop, While, Break, For, True, False, Null, And, Not, Or,
],
)
}
@ -611,6 +614,8 @@ mod test {
"nor",
"andnowQuestionMark",
"notOrAnd",
"breakMe",
"Ibreak",
];
let sentences = words
.iter()

View file

@ -1,4 +1,5 @@
mod alloc;
mod ast;
mod errors;
mod lex;
mod parse;