symbol literal.

main
bog 2024-03-02 14:59:24 +01:00
parent c45b885dc5
commit 76e5db35b4
6 changed files with 93 additions and 2 deletions

View File

@ -17,5 +17,6 @@ BUILTIN ::=
| float
| int
| string
| symbol
ARRAY ::= osquare EXPR* csquare

View File

@ -155,6 +155,33 @@ impl Lexer {
None
}
fn scan_symbol(&self) -> Option<Token> {
let mut value = String::from("");
let offset = 1;
if let Some('\'') = self.text.chars().nth(self.cursor) {
} else {
return None;
}
for c in self.text.chars().skip(self.cursor + offset) {
if c.is_whitespace() || c == ';' {
break;
}
value.push(c);
}
if value.len() > 0 {
Some(Token {
position: self.cursor + offset + value.len(),
value
})
} else {
None
}
}
fn scan_int(&self) -> Option<Token> {
let mut value = String::from("");
@ -369,6 +396,12 @@ impl Iterator for Lexer {
}
}
if let Some(token) = self.scan_symbol() {
self.cursor = token.position;
return Some(Contextual(Node::Symbol(token.value.clone()),
Context(self.line)))
}
if let Some(token) = self.scan_identifier() {
self.cursor = token.position;
return Some(Contextual(Node::Ident(token.value.clone()),
@ -401,7 +434,7 @@ mod test {
}
return Err(error::AstError {
msg: format!("unknown symbol <{}>", val),
msg: format!("unknown text <{}>", val),
line: lexer.line
});
}
@ -519,6 +552,29 @@ mod test {
Ok(())
}
#[test]
fn test_symbols() -> Result<(), error::AstError> {
let mut lex = Lexer::new();
let res = lexer_run(&mut lex,
" 'abc '+-*/ 'a; ")?;
assert_eq!(4, res.len());
assert_eq!(Node::Symbol(String::from("abc")),
res.get(0).unwrap().0);
assert_eq!(Node::Symbol(String::from("+-*/")),
res.get(1).unwrap().0);
assert_eq!(Node::Symbol(String::from("a")),
res.get(2).unwrap().0);
assert_eq!(Node::Semicolon, res.get(3).unwrap().0);
Ok(())
}
#[test]
fn test_variables() -> Result<(), error::AstError> {
let mut lex = Lexer::new();

View File

@ -8,6 +8,7 @@ pub enum Node {
Int(i32),
Float(f64),
String(String),
Symbol(String),
OSquare,
CSquare,
Array(Vec<Contextual<Node>>),

View File

@ -176,6 +176,10 @@ impl Parser {
Contextual(Node::String(value), ctx)
=> Ok(Some(Contextual(Node::String(value), ctx))),
Contextual(Node::Symbol(value), ctx)
=> Ok(Some(Contextual(Node::Symbol(value), ctx))),
_ => {
Err(error::AstError {
msg: String::from(format!("unexpected {:?}", node)),
@ -279,11 +283,25 @@ mod test {
Ok(())
}
#[test]
fn symbols() -> TestResult {
test_parser(
Node::Module("mod".to_owned(), vec![
Contextual(Node::Symbol(String::from("bonjour++")),
Context(0))
]),
" 'bonjour++ ; "
)?;
Ok(())
}
#[test]
fn strings() -> TestResult {
test_parser(
Node::Module("mod".to_owned(), vec![
Contextual(Node::String(String::from("pizza! ")), Context(0))
Contextual(Node::String(String::from("pizza! ")),
Context(0))
]),
" \"pizza! \"; "
)?;
@ -339,6 +357,7 @@ mod test {
)?;
Ok(())
}
#[test]
fn arrays() -> TestResult {
test_parser(

View File

@ -139,8 +139,13 @@ impl Evaluator {
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::Symbol(value)
=> Ok(Some(Value::Symbol(value.clone()))),
Node::Array(nodes) => {
let mut values: Vec<Value> = vec![];
@ -274,6 +279,14 @@ mod test {
Ok(())
}
#[test]
fn symbols() -> TestResult {
test_eval_value(Value::Symbol(String::from("bim-bam")),
" 'bim-bam ; ")?;
Ok(())
}
#[test]
fn arrays() -> TestResult {
test_eval_value(

View File

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