diff --git a/forge_core/src/ast.rs b/forge_core/src/ast.rs index 6539d64..00fabac 100644 --- a/forge_core/src/ast.rs +++ b/forge_core/src/ast.rs @@ -5,33 +5,12 @@ pub struct Program(pub Vec); pub enum Declaration { Function(Function), Global(Global), - Struct(Struct), Const(Const), } -#[derive(PartialEq, Clone, Debug, Default)] -pub struct Varinfo { - pub typename: Option, - pub size: Option, -} - #[derive(PartialEq, Clone, Debug)] pub struct Global { pub name: String, - pub typename: Option, - pub size: Option, -} - -#[derive(PartialEq, Clone, Debug)] -pub struct Struct { - pub name: String, - pub members: Vec, -} - -#[derive(PartialEq, Clone, Debug)] -pub struct Member { - pub name: String, - pub typename: Option, pub size: Option, } @@ -48,16 +27,10 @@ pub struct Block(pub Vec); #[derive(PartialEq, Clone, Debug)] pub struct Function { pub name: String, - pub args: Vec, + pub args: Vec, pub body: Block, } -#[derive(Eq, PartialEq, Clone, Debug)] -pub struct Argname { - pub name: String, - pub typename: Option, -} - #[derive(PartialEq, Clone, Debug)] pub enum Statement { Return(Return), @@ -106,7 +79,6 @@ impl From for Lvalue { #[derive(PartialEq, Clone, Debug)] pub struct VarDecl { pub name: String, - pub typename: Option, pub size: Option, pub initial: Option, } @@ -154,12 +126,6 @@ pub enum Operator { Rshift, } -#[derive(Debug, PartialEq, Clone)] -pub enum Suffix { - Subscript(BoxExpr), - Member(String), -} - #[derive(Debug, PartialEq, Clone)] pub enum Expr { Number(i32), diff --git a/forge_core/src/compiler.rs b/forge_core/src/compiler.rs index 2f831a8..0e85752 100644 --- a/forge_core/src/compiler.rs +++ b/forge_core/src/compiler.rs @@ -183,7 +183,6 @@ impl Compilable for Declaration { match self { Declaration::Function(f) => f.process(state, None), Declaration::Global(g) => g.process(state, None), - Declaration::Struct(_) => todo!("Structs are not yet supported"), Declaration::Const(c) => c.process(state, None), } } @@ -201,10 +200,7 @@ impl Compilable for Function { // Add each argument as a local for arg in self.args { - if arg.typename.is_some() { - todo!("Structs are not yet supported") - } - sig.add_local(&arg.name)? + sig.add_local(&arg)? } // todo we need to store arity somehow in the state, so we can check arglists even @@ -271,8 +267,8 @@ impl Compilable for Assignment { impl Compilable for VarDecl { fn process(self, state: &mut State, sig: Option<&mut CompiledFn>) -> Result<(), CompileError> { let sig = sig.expect("Var declaration outside function"); - if self.typename.is_some() || self.size.is_some() { - todo!("Structs and arrays are not yet supported") + if self.size.is_some() { + todo!("Arrays are not yet supported") } if let Some(initial) = self.initial { // If it's got an initial value, we have to compile that before we add @@ -492,8 +488,8 @@ impl Compilable for Expr { impl Compilable for Global { fn process(self, state: &mut State, _: Option<&mut CompiledFn>) -> Result<(), CompileError> { - if self.typename.is_some() || self.size.is_some() { - todo!("Structs and arrays are not yet supported") + if self.size.is_some() { + todo!("Arrays are not yet supported") } state.add_global(&self.name, |s| Variable::IndirectLabel(s.gensym())) } diff --git a/forge_core/src/forge_parser.rs b/forge_core/src/forge_parser.rs index d207d2b..3defe3c 100644 --- a/forge_core/src/forge_parser.rs +++ b/forge_core/src/forge_parser.rs @@ -25,7 +25,6 @@ lazy_static::lazy_static! { .op(Op::prefix(Rule::prefix)) .op(Op::postfix(Rule::arglist)) .op(Op::postfix(Rule::subscript)) - .op(Op::postfix(Rule::member)) }; } @@ -156,7 +155,6 @@ impl AstNode for Declaration { match pair.as_rule() { Rule::function => Self::Function(Function::from_pair(pair)), Rule::global => Self::Global(Global::from_pair(pair)), - Rule::struct_decl => Self::Struct(Struct::from_pair(pair)), Rule::const_decl => Self::Const(Const::from_pair(pair)), _ => unreachable!(), } @@ -165,70 +163,14 @@ impl AstNode for Declaration { /////////////////////////////////////////////////////////////////////////////////////////// -impl Varinfo { - fn read_or_default(mut pairs: Peekable) -> Self { - pairs - .next_if_rule(Rule::varinfo) - .map_or(Self::default(), Self::from_pair) - } -} - -impl AstNode for Varinfo { - const RULE: Rule = Rule::varinfo; - fn from_pair(pair: Pair) -> Self { - let mut children = pair.into_inner().peekable(); - let typename = children - .next_if_rule(Rule::typename) - .map(|t| String::from(t.first().as_str())); - let size = children - .next_if_rule(Rule::size) - .map(|s| Expr::from_pair(s.first())); - Self { typename, size } - } -} - -/////////////////////////////////////////////////////////////////////////////////////////// - impl AstNode for Global { const RULE: Rule = Rule::global; fn from_pair(pair: Pair) -> Self { let mut inner = pair.into_inner().peekable(); let name = String::from(inner.next().unwrap().as_str()); - let Varinfo { typename, size } = Varinfo::read_or_default(inner); + let size = inner.next().map(Expr::from_pair); - Global { - name, - typename, - size, - } - } -} - -/////////////////////////////////////////////////////////////////////////////////////////// - -impl AstNode for Struct { - const RULE: Rule = Rule::struct_decl; - fn from_pair(pair: Pair<'_>) -> Self { - let mut inner = pair.into_inner(); - let name = String::from(inner.next().unwrap().as_str()); - let member_pairs = inner.next().unwrap().into_inner(); - let members: Vec<_> = member_pairs.map(Member::from_pair).collect(); - Struct { name, members } - } -} - -impl AstNode for Member { - const RULE: Rule = Rule::member; - fn from_pair(pair: Pair<'_>) -> Self { - let mut inner = pair.into_inner().peekable(); - let name = String::from(inner.next().unwrap().as_str()); - let Varinfo { typename, size } = Varinfo::read_or_default(inner); - - Member { - name, - typename, - size, - } + Global { name, size } } } @@ -267,7 +209,7 @@ impl AstNode for Function { .next() .unwrap() .into_inner() - .map(Argname::from_pair) + .map(|p| String::from(p.as_str())) .collect(); let body = Block::from_pair(inner.next().unwrap()); @@ -276,16 +218,6 @@ impl AstNode for Function { } } -impl AstNode for Argname { - const RULE: Rule = Rule::argname; - fn from_pair(pair: Pair<'_>) -> Self { - let mut inner = pair.into_inner().peekable(); - let name = String::from(inner.next().unwrap().as_str()); - let typename = inner.next().map(|t| String::from(t.first().as_str())); - Self { name, typename } - } -} - /////////////////////////////////////////////////////////////////////////////////////////// impl AstNode for Statement { @@ -335,14 +267,18 @@ impl AstNode for VarDecl { fn from_pair(pair: Pair) -> Self { let mut inner = pair.into_inner(); let name = String::from(inner.next().unwrap().as_str()); - let Varinfo { typename, size } = Varinfo::from_pair(inner.next().unwrap()); - let initial = inner.next().map(Expr::from_pair); - Self { - name, - typename, - size, - initial, + let mut size = None; + let mut initial = None; + + for p in inner { + match p.as_rule() { + Rule::size => { size = Some(Expr::from_pair(p.first())) } + Rule::expr => { initial = Some(Expr::from_pair(p)) } + _ => unreachable!() + } } + + Self { name, size, initial } } } @@ -441,7 +377,6 @@ impl AstNode for Expr { Rule::subscript => { Expr::Subscript(expr.into(), Expr::from_pair(suffix.first()).into()) } - Rule::member => Expr::Member(expr.into(), suffix.first_as_string()), _ => unreachable!(), }) .parse(pair.into_inner()) @@ -485,22 +420,6 @@ impl AstNode for Operator { /////////////////////////////////////////////////////////////////////////////////////////// -impl AstNode for Suffix { - const RULE: Rule = Rule::suffix; - - fn from_pair(pair: Pair) -> Self { - let first = pair.first(); - match first.as_rule() { - Rule::subscript => Self::Subscript(Expr::from_pair(first.first()).into()), - Rule::member => Self::Member(first.first_as_string()), - //Rule::arglist => Self::Arglist(first.into_inner().map(Rvalue::from_pair).collect()), - rule => unreachable!("Expected a subscript or member, got a {:?}", rule), - } - } -} - -/////////////////////////////////////////////////////////////////////////////////////////// - impl AstNode for Program { const RULE: Rule = Rule::program; fn from_pair(pair: Pair) -> Self { @@ -527,31 +446,13 @@ mod test { Global::from_str("global foo;"), Ok(Global { name: "foo".into(), - typename: None, size: None, }) ); - assert_eq!( - Global::from_str("global foo:Thing;"), - Ok(Global { - name: "foo".into(), - typename: Some("Thing".into()), - size: None, - }) - ); - assert_eq!( - Global::from_str("global foo:Thing[10];"), - Ok(Global { - name: "foo".into(), - typename: Some("Thing".into()), - size: Some(10.into()), - }) - ); assert_eq!( Global::from_str("global foo[10];"), Ok(Global { name: "foo".into(), - typename: None, size: Some(10.into()), }) ); @@ -593,52 +494,6 @@ mod test { ) } - #[test] - fn parse_structs() { - assert_eq!( - Struct::from_str("struct Point { x, y }"), - Ok(Struct { - name: "Point".into(), - members: vec![ - Member { - name: "x".into(), - typename: None, - size: None, - }, - Member { - name: "y".into(), - typename: None, - size: None, - }, - ], - }) - ); - - assert_eq!( - Struct::from_str("struct Foo { bar[100] }"), - Ok(Struct { - name: "Foo".into(), - members: vec![Member { - name: "bar".into(), - typename: None, - size: Some(100.into()), - },], - }) - ); - - assert_eq!( - Struct::from_str("struct Foo { bar:Thing[100] }"), - Ok(Struct { - name: "Foo".into(), - members: vec![Member { - name: "bar".into(), - typename: Some("Thing".into()), - size: Some(100.into()), - },], - }) - ); - } - #[test] fn parse_function_headers() { assert_eq!( @@ -653,45 +508,10 @@ mod test { Function::from_str("fn foo(a, b) {}"), Ok(Function { name: "foo".into(), - args: vec![ - Argname { - name: "a".into(), - typename: None, - }, - Argname { - name: "b".into(), - typename: None, - }, - ], + args: vec!["a".into(), "b".into()], body: Block(vec![]), }) ); - assert_eq!( - Function::from_str("fn foo(a:Blah, b) {}"), - Ok(Function { - name: "foo".into(), - args: vec![ - Argname { - name: "a".into(), - typename: Some("Blah".into()), - }, - Argname { - name: "b".into(), - typename: None, - }, - ], - body: Block(vec![]), - }) - ); - - let func = Function { - name: "foo".into(), - args: vec![Argname { - name: "a".into(), - typename: None, - }], - body: Block(vec![]), - }; } #[test] @@ -731,10 +551,10 @@ mod test { // Multi-suffix assert_eq!( - Expr::from_str("foo[10].bar"), - Ok(Expr::Member( + Expr::from_str("foo[10][3]"), + Ok(Expr::Subscript( Expr::Subscript("foo".into(), 10.into()).into(), - "bar".into() + 3.into() )) ); @@ -812,8 +632,8 @@ mod test { // Addresses assert_eq!( - Expr::from_str("&foo.bar"), - Ok(Expr::Address(Expr::Member("foo".into(), "bar".into()).into())) + Expr::from_str("&foo[7]"), + Ok(Expr::Address(Expr::Subscript("foo".into(), 7.into()).into())) ); assert_eq!( @@ -914,17 +734,15 @@ mod test { Statement::from_str("var blah;"), Ok(Statement::VarDecl(VarDecl { name: "blah".into(), - typename: None, size: None, initial: None, })) ); assert_eq!( - VarDecl::from_str("var blah:Foo[7] = 35"), + VarDecl::from_str("var blah[7] = 35"), Ok(VarDecl { name: "blah".into(), - typename: Some("Foo".into()), size: Some(7.into()), initial: Some(35.into()), }) @@ -998,10 +816,10 @@ mod test { #[test] fn parse_program() { assert_eq!( - Program::from_str("global foo; struct Point { x, y }"), + Program::from_str("global foo; fn blah(x) { return x + 3; }"), Ok(Program(vec![ Declaration::from_str("global foo;").unwrap(), - Declaration::from_str("struct Point { x, y }").unwrap(), + Declaration::from_str("fn blah(x) { return x + 3; }").unwrap(), ])) ) } diff --git a/forge_core/src/new.pest b/forge_core/src/new.pest index 026b5c8..7ccbf3e 100644 --- a/forge_core/src/new.pest +++ b/forge_core/src/new.pest @@ -65,11 +65,9 @@ operator = _{ expr = { prefix* ~ term ~ suffix* ~ (operator ~ prefix* ~ term ~ suffix*)* } term = _{ number | name | "(" ~ expr ~ ")" | string } -suffix = _{ modifier | arglist } -modifier = _{ subscript | member } +suffix = _{ subscript | arglist } subscript = { "[" ~ expr ~ "]" } arglist = { "(" ~ (expr ~ ("," ~ expr)*)? ~ ")" } -member = { "." ~ name } statement = { asm | ((return_stmt | var_decl | assignment | expr) ~ ";") | conditional | while_loop | repeat_loop } @@ -80,23 +78,16 @@ asm_body = { (!"}" ~ ANY)* } block = { "{" ~ statement* ~ "}" } function = { "fn" ~ name ~ argnames ~ block } -argnames = { "(" ~ (argname ~ ("," ~ argname)*)? ~ ")" } -argname = { name ~ typename? } +argnames = { "(" ~ (name ~ ("," ~ name)*)? ~ ")" } -declaration = { function | global | struct_decl | const_decl } +declaration = { function | global | const_decl } program = { (COMMENT | WHITESPACE)? ~ declaration* ~ EOI } return_stmt = { "return" ~ expr? } conditional = { "if" ~ "(" ~ expr ~ ")" ~ block ~ ("else" ~ block)? } while_loop = { "while" ~ "(" ~ expr ~ ")" ~ block } repeat_loop = { "repeat" ~ "(" ~ expr ~ ")" ~ name? ~ block } -var_decl = { "var" ~ name ~ varinfo ~ ("=" ~ expr)? } -global = { "global" ~ name ~ varinfo ~ ";" } -typename = { ":" ~ name } +var_decl = { "var" ~ name ~ size? ~ ("=" ~ expr)? } +global = { "global" ~ name ~ size? ~ ";" } size = { "[" ~ expr ~ "]" } const_decl = { "const" ~ name ~ "=" ~ (string | expr) ~ ";" } - -struct_decl = { "struct" ~ name ~ "{" ~ members ~ "}" } -member_decl = { name ~ varinfo } -members = { (member_decl ~ ("," ~ member_decl)*)? } -varinfo = { typename? ~ size? }