Allowing expressions in a couple places that used to be literal numbers
This commit is contained in:
+10
-10
@@ -9,36 +9,36 @@ pub enum Declaration {
|
|||||||
Const(Const),
|
Const(Const),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Clone, Debug, Default)]
|
#[derive(PartialEq, Clone, Debug, Default)]
|
||||||
pub struct Varinfo {
|
pub struct Varinfo {
|
||||||
pub typename: Option<String>,
|
pub typename: Option<String>,
|
||||||
pub size: Option<i32>,
|
pub size: Option<Node>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Clone, Debug)]
|
#[derive(PartialEq, Clone, Debug)]
|
||||||
pub struct Global {
|
pub struct Global {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub typename: Option<String>,
|
pub typename: Option<String>,
|
||||||
pub size: Option<i32>,
|
pub size: Option<Node>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Clone, Debug)]
|
#[derive(PartialEq, Clone, Debug)]
|
||||||
pub struct Struct {
|
pub struct Struct {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub members: Vec<Member>,
|
pub members: Vec<Member>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Clone, Debug)]
|
#[derive(PartialEq, Clone, Debug)]
|
||||||
pub struct Member {
|
pub struct Member {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub typename: Option<String>,
|
pub typename: Option<String>,
|
||||||
pub size: Option<i32>,
|
pub size: Option<Node>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Clone, Debug)]
|
#[derive(PartialEq, Clone, Debug)]
|
||||||
pub struct Const {
|
pub struct Const {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub value: Option<i32>, // todo: this should take a Node
|
pub value: Option<Node>,
|
||||||
pub string: Option<String>,
|
pub string: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ pub enum Rvalue {
|
|||||||
pub struct VarDecl {
|
pub struct VarDecl {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub typename: Option<String>,
|
pub typename: Option<String>,
|
||||||
pub size: Option<i32>,
|
pub size: Option<Node>,
|
||||||
pub initial: Option<Node>,
|
pub initial: Option<Node>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,11 @@ name_char = { ASCII_ALPHA_LOWER | ASCII_ALPHA_UPPER | "_" | "$" }
|
|||||||
name = @{ name_char ~ (name_char | ASCII_DIGIT)* }
|
name = @{ name_char ~ (name_char | ASCII_DIGIT)* }
|
||||||
|
|
||||||
dec_number = @{ ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* }
|
dec_number = @{ ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* }
|
||||||
// Literal numbers use this rule, but in exprs it's the prefix operator. The difference
|
|
||||||
// is that some things (const initialization) only accept literal numbers.
|
|
||||||
neg_number = ${ "-" ~ dec_number }
|
|
||||||
hex_number = ${ "0x" ~ ASCII_HEX_DIGIT+ }
|
hex_number = ${ "0x" ~ ASCII_HEX_DIGIT+ }
|
||||||
bin_number = ${ "0b" ~ ASCII_BIN_DIGIT+ }
|
bin_number = ${ "0b" ~ ASCII_BIN_DIGIT+ }
|
||||||
oct_number = ${ "0o" ~ ASCII_OCT_DIGIT+ }
|
oct_number = ${ "0o" ~ ASCII_OCT_DIGIT+ }
|
||||||
dec_zero = @{ "0" }
|
dec_zero = @{ "0" }
|
||||||
number = { dec_number | hex_number | bin_number | oct_number | dec_zero | neg_number }
|
number = { dec_number | hex_number | bin_number | oct_number | dec_zero }
|
||||||
|
|
||||||
escape = @{ "\\" ~ ("t" | "r" | "n" | "0" | "\\" | "\"") }
|
escape = @{ "\\" ~ ("t" | "r" | "n" | "0" | "\\" | "\"") }
|
||||||
string_inner = ${ !("\"" | "\\") ~ ANY | escape }
|
string_inner = ${ !("\"" | "\\") ~ ANY | escape }
|
||||||
@@ -90,8 +87,8 @@ repeat_loop = { "repeat" ~ "(" ~ expr ~ ")" ~ name? ~ block }
|
|||||||
var_decl = { "var" ~ name ~ varinfo ~ ("=" ~ expr)? }
|
var_decl = { "var" ~ name ~ varinfo ~ ("=" ~ expr)? }
|
||||||
global = { "global" ~ name ~ varinfo ~ ";" }
|
global = { "global" ~ name ~ varinfo ~ ";" }
|
||||||
typename = { ":" ~ name }
|
typename = { ":" ~ name }
|
||||||
size = { "[" ~ number ~ "]" }
|
size = { "[" ~ expr ~ "]" }
|
||||||
const_decl = { "const" ~ name ~ "=" ~ (number | string) ~ ";" }
|
const_decl = { "const" ~ name ~ "=" ~ (expr | string) ~ ";" }
|
||||||
|
|
||||||
struct_decl = { "struct" ~ name ~ "{" ~ members ~ "}" }
|
struct_decl = { "struct" ~ name ~ "{" ~ members ~ "}" }
|
||||||
member = { name ~ varinfo }
|
member = { name ~ varinfo }
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ impl<'a> PairExt for Pair<'a> {
|
|||||||
fn into_number(self) -> i32 {
|
fn into_number(self) -> i32 {
|
||||||
let first = self.into_inner().next().unwrap();
|
let first = self.into_inner().next().unwrap();
|
||||||
match first.as_rule() {
|
match first.as_rule() {
|
||||||
Rule::dec_number | Rule::dec_zero | Rule::neg_number => {
|
Rule::dec_number | Rule::dec_zero => i32::from_str(first.as_str()).unwrap(),
|
||||||
i32::from_str(first.as_str()).unwrap()
|
|
||||||
}
|
|
||||||
Rule::hex_number => i32::from_str_radix(first.as_str().get(2..).unwrap(), 16).unwrap(),
|
Rule::hex_number => i32::from_str_radix(first.as_str().get(2..).unwrap(), 16).unwrap(),
|
||||||
Rule::bin_number => i32::from_str_radix(first.as_str().get(2..).unwrap(), 2).unwrap(),
|
Rule::bin_number => i32::from_str_radix(first.as_str().get(2..).unwrap(), 2).unwrap(),
|
||||||
Rule::oct_number => i32::from_str_radix(first.as_str().get(2..).unwrap(), 8).unwrap(),
|
Rule::oct_number => i32::from_str_radix(first.as_str().get(2..).unwrap(), 8).unwrap(),
|
||||||
@@ -177,7 +175,7 @@ impl AstNode for Varinfo {
|
|||||||
.map(|t| String::from(t.first().as_str()));
|
.map(|t| String::from(t.first().as_str()));
|
||||||
let size = children
|
let size = children
|
||||||
.next_if_rule(Rule::size)
|
.next_if_rule(Rule::size)
|
||||||
.map(|s| s.first().into_number());
|
.map(|s| Node::from_pair(s.first()));
|
||||||
Self { typename, size }
|
Self { typename, size }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,10 +239,10 @@ impl AstNode for Const {
|
|||||||
string: Some(value.into_quoted_string()),
|
string: Some(value.into_quoted_string()),
|
||||||
value: None,
|
value: None,
|
||||||
},
|
},
|
||||||
Rule::number => Const {
|
Rule::expr => Const {
|
||||||
name,
|
name,
|
||||||
string: None,
|
string: None,
|
||||||
value: Some(value.into_number()),
|
value: Some(Node::from_pair(value)),
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
@@ -576,7 +574,7 @@ mod test {
|
|||||||
Ok(Global {
|
Ok(Global {
|
||||||
name: "foo".into(),
|
name: "foo".into(),
|
||||||
typename: Some("Thing".into()),
|
typename: Some("Thing".into()),
|
||||||
size: Some(10)
|
size: Some(Node::Number(10))
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -584,7 +582,7 @@ mod test {
|
|||||||
Ok(Global {
|
Ok(Global {
|
||||||
name: "foo".into(),
|
name: "foo".into(),
|
||||||
typename: None,
|
typename: None,
|
||||||
size: Some(10)
|
size: Some(Node::Number(10))
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -595,7 +593,7 @@ mod test {
|
|||||||
Const::from_str("const a = 123;"),
|
Const::from_str("const a = 123;"),
|
||||||
Ok(Const {
|
Ok(Const {
|
||||||
name: "a".into(),
|
name: "a".into(),
|
||||||
value: Some(123),
|
value: Some(Node::Number(123)),
|
||||||
string: None
|
string: None
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -603,7 +601,7 @@ mod test {
|
|||||||
Const::from_str("const a = 0xaa;"),
|
Const::from_str("const a = 0xaa;"),
|
||||||
Ok(Const {
|
Ok(Const {
|
||||||
name: "a".into(),
|
name: "a".into(),
|
||||||
value: Some(0xaa),
|
value: Some(Node::Number(0xaa)),
|
||||||
string: None
|
string: None
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -611,7 +609,10 @@ mod test {
|
|||||||
Const::from_str("const a = -7;"),
|
Const::from_str("const a = -7;"),
|
||||||
Ok(Const {
|
Ok(Const {
|
||||||
name: "a".into(),
|
name: "a".into(),
|
||||||
value: Some(-7),
|
value: Some(Node::Prefix(
|
||||||
|
crate::ast::Prefix::Neg,
|
||||||
|
Node::Number(7).into()
|
||||||
|
)),
|
||||||
string: None
|
string: None
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -653,7 +654,7 @@ mod test {
|
|||||||
members: vec![Member {
|
members: vec![Member {
|
||||||
name: "bar".into(),
|
name: "bar".into(),
|
||||||
typename: None,
|
typename: None,
|
||||||
size: Some(100)
|
size: Some(Node::Number(100))
|
||||||
},]
|
},]
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -665,7 +666,7 @@ mod test {
|
|||||||
members: vec![Member {
|
members: vec![Member {
|
||||||
name: "bar".into(),
|
name: "bar".into(),
|
||||||
typename: Some("Thing".into()),
|
typename: Some("Thing".into()),
|
||||||
size: Some(100)
|
size: Some(Node::Number(100))
|
||||||
},]
|
},]
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -963,7 +964,7 @@ mod test {
|
|||||||
Ok(VarDecl {
|
Ok(VarDecl {
|
||||||
name: "blah".into(),
|
name: "blah".into(),
|
||||||
typename: Some("Foo".into()),
|
typename: Some("Foo".into()),
|
||||||
size: Some(7),
|
size: Some(Node::Number(7)),
|
||||||
initial: Some(Node::Number(35)),
|
initial: Some(Node::Number(35)),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user