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