array values.

main
bog 2024-03-01 18:44:16 +01:00
parent 35e8cc813e
commit 4e7e7ad07b
6 changed files with 116 additions and 17 deletions

View File

@ -1,8 +1,11 @@
MODULE ::= INSTR*
INSTR ::= EXPR semicolon
EXPR ::= BUILTIN
EXPR ::= LITERAL
LITERAL ::= BUILTIN | ARRAY
BUILTIN ::=
| bool
| float
| int
| string
ARRAY ::= osquare EXPR* csquare

View File

@ -19,7 +19,7 @@ impl Lexer {
line: 1,
text: String::from(""),
separators: vec![
';'
';', '[', ']'
]
}
}
@ -242,6 +242,7 @@ impl Lexer {
self.cursor += 1;
}
self.skip_spaces();
}
}
@ -254,6 +255,16 @@ impl Iterator for Lexer {
self.skip_spaces();
self.skip_comments();
if let Some(token) = self.scan_text("[") {
self.cursor = token.position;
return Some(Node::OSquare);
}
if let Some(token) = self.scan_text("]") {
self.cursor = token.position;
return Some(Node::CSquare);
}
if let Some(token) = self.scan_keyword("true") {
self.cursor = token.position;
return Some(Node::Bool(token.value == "true"));
@ -417,4 +428,18 @@ mod test {
Ok(())
}
#[test]
fn test_arrays() -> Result<(), error::AstError> {
let mut lex = Lexer::new();
let res = lexer_run(&mut lex,
" [ ] ")?;
assert_eq!(2, res.len());
assert_eq!(Node::OSquare, *res.get(0).unwrap());
assert_eq!(Node::CSquare, *res.get(1).unwrap());
Ok(())
}
}

View File

@ -6,6 +6,9 @@ pub enum Node {
Int(i32),
Float(f64),
String(String),
OSquare,
CSquare,
Array(Vec<Node>),
Semicolon
}

View File

@ -62,34 +62,49 @@ impl Parser {
}
fn parse_expr(&mut self) -> ParseResult {
self.parse_builtin()
self.parse_literal()
}
fn parse_builtin(&mut self) -> ParseResult {
fn parse_literal(&mut self) -> ParseResult {
match self.lexer.next() {
Some(Node::Int(value))
Some(Node::OSquare) => self.parse_array(),
Some(node) => self.parse_builtin(node),
None => Ok(None)
}
}
fn parse_builtin(&mut self, node: Node) -> ParseResult {
match node {
Node::Int(value)
=> Ok(Some(Node::Int(value))),
Some(Node::Float(value))
Node::Float(value)
=> Ok(Some(Node::Float(value))),
Some(Node::Bool(value))
Node::Bool(value)
=> Ok(Some(Node::Bool(value))),
Some(Node::String(value))
Node::String(value)
=> Ok(Some(Node::String(value))),
Some(other) => {
_ => {
Err(error::AstError {
msg: String::from(format!("unexpected {:?}", other)),
msg: String::from(format!("unexpected {:?}", node)),
line: self.lexer.line()
})
}
None => Ok(None)
}
}
fn parse_array(&mut self) -> ParseResult {
let mut elements: Vec<Node> = vec![];
while let Ok(Some(expr)) = self.parse_expr() {
elements.push(expr);
}
Ok(Some(Node::Array(elements)))
}
}
#[cfg(test)]
@ -179,4 +194,20 @@ mod test {
Ok(())
}
#[test]
fn arrays() -> TestResult {
test_parser(
Node::Module("mod".to_owned(), vec![
Node::Array(vec![
Node::Int(2),
Node::Float(3.2),
Node::Bool(true)
])
]),
" [2 3.2 true]; "
)?;
Ok(())
}
}

View File

@ -29,11 +29,32 @@ impl Evaluator {
Ok(res)
},
Node::Bool(value) => Ok(Some(Value::Bool(*value))),
Node::Int(value) => Ok(Some(Value::Int(*value))),
Node::Float(value) => Ok(Some(Value::Float(*value))),
Node::String(value) => Ok(Some(Value::String(value.clone()))),
Node::String(value)
=> Ok(Some(Value::String(value.clone()))),
Node::Array(nodes) => {
let mut values: Vec<Value> = vec![];
for node in nodes {
match self.run(node) {
Ok(Some(value)) => {
values.push(value);
},
_ => {
return Err(EvalError {
msg: String::from("invalid array element"),
line: 0
});
}
}
}
Ok(Some(Value::Array(values)))
}
_ => Ok(None)
}
@ -98,9 +119,24 @@ mod test {
#[test]
fn strings() -> TestResult {
test_eval_value(Value::String(String::from(" pizzza!!!")),
test_eval_value(Value::String(String::from(" pizzza!!!")),
" \" pizzza!!!\"; ")?;
Ok(())
}
#[test]
fn arrays() -> TestResult {
test_eval_value(
Value::Array(
vec![
Value::Int(2),
Value::Int(4),
Value::Float(6.1)
]
),
" [2 4 6.1]; ")?;
Ok(())
}
}

View File

@ -4,6 +4,7 @@ pub enum Value {
Bool(bool),
Int(i32),
Float(f64),
String(String)
String(String),
Array(Vec<Value>)
}