Objects, strings

This commit is contained in:
Dane Johnson 2022-02-14 14:55:09 -06:00
parent 51531b806f
commit 15055b9ece
2 changed files with 29 additions and 3 deletions

View File

@ -19,7 +19,7 @@ fn script(filename: &str) {
let mut prgm = String::new(); let mut prgm = String::new();
file.read_to_string(&mut prgm).unwrap(); file.read_to_string(&mut prgm).unwrap();
let tree = parser::parse(&prgm); let tree = parser::parse(&prgm);
println!("{:?}", tree); println!("{:#?}", tree);
} }
fn main() { fn main() {

View File

@ -8,6 +8,7 @@ pub enum Stmt {
#[derive(Debug,PartialEq,Clone)] #[derive(Debug,PartialEq,Clone)]
pub enum Expr { pub enum Expr {
Id(String), Id(String),
String(String),
Num(f64), Num(f64),
Funcall(String, Vec<Expr>), Funcall(String, Vec<Expr>),
Funcdef(Option<String>, Box<Expr>), Funcdef(Option<String>, Box<Expr>),
@ -17,6 +18,7 @@ pub enum Expr {
Div(Box<Expr>, Box<Expr>), Div(Box<Expr>, Box<Expr>),
Block(Vec<Stmt>), Block(Vec<Stmt>),
GuardedBlock(Box<GuardedBlock>), GuardedBlock(Box<GuardedBlock>),
Object(Vec<Stmt>),
} }
#[derive(Debug,PartialEq,Clone)] #[derive(Debug,PartialEq,Clone)]
@ -30,7 +32,7 @@ peg::parser! {
pub rule program() -> Vec<Stmt> pub rule program() -> Vec<Stmt>
= __* s:stmt()* { s } = __* s:stmt()* { s }
pub rule stmt() -> Stmt pub rule stmt() -> Stmt
= i:id() "<-" _ e:expr() stop() { Stmt::Assignment(i, e) } / = a:assignment() { a } /
f:funcall() stop() { Stmt::Funcall(f) } / f:funcall() stop() { Stmt::Funcall(f) } /
c:conditional() { c } c:conditional() { c }
rule expr() -> Expr = precedence! { rule expr() -> Expr = precedence! {
@ -41,14 +43,19 @@ peg::parser! {
e1:(@) "/" _ e2:@ { Expr::Div(Box::new(e1), Box::new(e2)) } e1:(@) "/" _ e2:@ { Expr::Div(Box::new(e1), Box::new(e2)) }
-- --
"(" _ e:expr() ")" _ { e } "(" _ e:expr() ")" _ { e }
['"'] s:$((!['"'] [_] / r#"\""#)*) ['"'] { Expr::String(s.to_string()) }
f:funcall() { f } f:funcall() { f }
f:funcdef() { f } f:funcdef() { f }
o:object() { o }
i:id() _ { Expr::Id(i) } i:id() _ { Expr::Id(i) }
n:num() _ { Expr::Num(n) } n:num() _ { Expr::Num(n) }
} }
rule id() -> String rule id() -> String
= i:$(letter() (letter() / digit() / ['?'|'.'|'-'])*) _ { i.to_string() } = i:$(letter() (letter() / digit() / ['?'|'.'|'-'])*) _ { i.to_string() }
rule assignment() -> Stmt
= i:id() "<-" _ e:expr() stop() { Stmt::Assignment(i, e) }
rule num() -> f64 rule num() -> f64
= n:$(digit()+ "."? digit()* / "." digit()+) _ { n.parse().unwrap() } = n:$(digit()+ "."? digit()* / "." digit()+) _ { n.parse().unwrap() }
rule funcall() -> Expr rule funcall() -> Expr
@ -57,6 +64,9 @@ peg::parser! {
= i:id()? "->" _ e:(expr() / block()) { Expr::Funcdef(i, Box::new(e)) } = i:id()? "->" _ e:(expr() / block()) { Expr::Funcdef(i, Box::new(e)) }
rule conditional() -> Stmt rule conditional() -> Stmt
= i:_if() __* ei:elif()* __* e:_else()? __* { Stmt::Conditional([vec![i], ei].concat(), e) } = i:_if() __* ei:elif()* __* e:_else()? __* { Stmt::Conditional([vec![i], ei].concat(), e) }
rule object() -> Expr
= "{" _ stop() indent() __* a:assignment()+ dedent() __* "}" _ { Expr::Object(a) }
rule _if() -> Expr rule _if() -> Expr
= "if" _ g:expr() b:indented_block() { = "if" _ g:expr() b:indented_block() {
Expr::GuardedBlock(Box::new(GuardedBlock { Expr::GuardedBlock(Box::new(GuardedBlock {
@ -305,6 +315,22 @@ else
)]; )];
assert_eq!(deelang_parser::program(prgm).unwrap(), expected); assert_eq!(deelang_parser::program(prgm).unwrap(), expected);
} }
#[test]
fn test_object() {
let prgm = r"fruit <- {
>>>apple <- 1
pear <- 2
<<<
}";
let expected = vec![Stmt::Assignment(
"fruit".to_string(),
Expr::Object(vec![
Stmt::Assignment("apple".to_string(), Expr::Num(1.0)),
Stmt::Assignment("pear".to_string(), Expr::Num(2.0)),
]),
)];
assert_eq!(deelang_parser::program(prgm).unwrap(), expected);
}
#[test] #[test]
fn test_preprocess() { fn test_preprocess() {