valhallac

Compiler for set-theoretic programming language.
git clone git://git.knutsen.co/valhallac
Log | Files | Refs | README | LICENSE

commit 5d67441adc65a9e2c9302b53b1cf5aab23ea29ae
parent 28cc46cf32cf377f3a24374404e0f17e289171ba
Author: Demonstrandum <moi@knutsen.co>
Date:   Thu, 18 Jul 2019 21:38:50 +0100

impl statement chaining by newlines and ;.

Diffstat:
Msrc/syntax/lexer.rs | 11++++++++++-
Msrc/syntax/parser.rs | 23+++++++++++++++++++----
Mtest.vh | 5+++--
3 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/src/syntax/lexer.rs b/src/syntax/lexer.rs @@ -40,7 +40,7 @@ impl RegexExt for Regex { const IDENT_CHARS : &str = r"\p{L}\?!'\-_"; lazy_static! { - static ref OP : Regex = re!(r"\A([\+\.\*\|\\/\&%\$\^\~><=¬@\-]+)"); + static ref OP : Regex = re!(r"\A([,\+\.\*\|\\/\&%\$\^\~<¬=@>\-]+|:{2,})"); static ref IDENT : Regex = re!(&format!(r"\A([{id}][{id}\p{{N}}]*)", id=IDENT_CHARS)); static ref SYM : Regex = re!(&format!(r"\A(:[{id}\p{{N}}]+)", id=IDENT_CHARS)); static ref NUM : Regex = re!(r"\A(\-?(?:(?:0[xX][0-9a-f]+)|(?:0[bB][01]+)|(?:0[Oo][0-7]+)|(?:(?:[0-9]+(?:\.[0-9]+)?(?:e[\+\-]?[0-9]+)?))))"); @@ -97,6 +97,15 @@ pub fn lex(string : &str) -> Vec<Token> { continue; } + if *maybe_vec == ": " { + token_stream.push(Token::new( + TokenType::Op, ":", + location::new(line, col, 1))); + col += 2; + current_char += 2; + continue; + } + let first_char = partial.chars().nth(0) .expect("Empty program was trying to be lexed."); // This should't happen. diff --git a/src/syntax/parser.rs b/src/syntax/parser.rs @@ -3,7 +3,7 @@ use super::ast; use super::operators; use token::{Token, TokenType}; -use ast::{Numerics, Nodes}; +use ast::Nodes; pub fn parse(stream : Vec<Token>) -> ast::Root { let mut environment = ParseEnvironment::new(stream); @@ -30,14 +30,29 @@ impl ParseEnvironment { } pub fn start(&mut self) { - let e = self.expr(0); - self.root.branches.push(e); + let mut current = self.stream.first(); + while current.is_some() && current.unwrap().class != TokenType::EOF { + if current.unwrap().class == TokenType::Term { + self.stream.remove(0); + current = self.stream.get(0); + continue; + } + let e = self.expr(0); + self.root.branches.push(e); + current = self.stream.get(0); + } } fn null_den(&mut self, token : &Token) -> Nodes { match token.class { TokenType::Ident => ast::IdentNode::new(&token.string), - TokenType::Op => ast::CallNode::new(ast::IdentNode::new(&token.string), vec![self.expr(300)]), + TokenType::Op => { // Prefix Op. + let op = self.optable.lookup(&token.string, 1); + if op.is_some() { + return ast::CallNode::new(ast::IdentNode::new(&token.string), vec![self.expr(300)]); + } + return panic!("`{}` is not a prefix operator.", token.string); + }, TokenType::Num => ast::NumNode::new(&*token.string), TokenType::Str => ast::StrNode::new(&token.string), _ => panic!("Passed non-atomic token to `atom` parser.") diff --git a/test.vh b/test.vh @@ -1 +1,2 @@ -a - b - c - d- \ No newline at end of file +f : A -> B -> C +a = n + 3+ \ No newline at end of file