From 86c2b13d1ae6353ad3a3481838e0a22a3b47a5d4 Mon Sep 17 00:00:00 2001 From: Teascade Date: Wed, 24 Jun 2020 19:29:16 +0300 Subject: [PATCH] Add functions --- reid_src/test.reid | 3 +- src/compiler.rs | 1 + src/parser/mod.rs | 126 ++++++++++++++++++++++++++++++-------- src/parser/parsed_reid.rs | 43 ++++++++++--- 4 files changed, 136 insertions(+), 37 deletions(-) diff --git a/reid_src/test.reid b/reid_src/test.reid index aeab6ca..3ed449c 100644 --- a/reid_src/test.reid +++ b/reid_src/test.reid @@ -1,2 +1 @@ -let otus = "dotus"; -let botus = otus; \ No newline at end of file +print(); \ No newline at end of file diff --git a/src/compiler.rs b/src/compiler.rs index 9738544..3039581 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -62,6 +62,7 @@ impl Compiler { self.list.push(Command::EndScope); Ok(None) } + Expression::FunctionCall(..) => Err(CompilerError::Fatal), Expression::ValueRef(_, val) => match val { Pattern::IdentPattern(pos, ident) => { if let Some(var) = self.root_scope.get(ident.clone()) { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 27d4d7b..921a328 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -17,6 +17,7 @@ const ALLOWED_IDENT_BEGIN_CHARS: [char; 26] = [ pub struct Parser { text: Vec, cursor: usize, + inconfidence: usize, line_number: usize, character_number: usize, } @@ -26,6 +27,7 @@ impl Parser { Parser { text: text.chars().collect(), cursor: 0, + inconfidence: 0, line_number: 0, character_number: 0, } @@ -37,7 +39,7 @@ impl Parser { let mut error = None; while { - self.skip_whitespace(); + self.skip_whitespace_confident(true); if self.remaining() > 0 { match Statement::parse(&mut self) { Ok(exp) => { @@ -76,12 +78,20 @@ impl Parser { } } - pub fn expect>(&mut self, expected: T) -> Expect { + pub fn expect>(&mut self, expectable: Expectable) -> Expect { + match expectable { + Expectable::Static(val) => self.expect_static(val), + Ident => self.expect_ident(), + StringLit => self.expect_string_lit(), + } + } + + pub fn expect_static>(&mut self, expected: T) -> Expect { let expected = expected.into(); self.skip_whitespace(); let mut result = Some(expected.clone()); for (idx, c) in expected.chars().enumerate() { - if let Some(peek) = self.peek(idx) { + if let Some(peek) = self.peek(idx + self.inconfidence) { if peek != c { result = None; } @@ -90,9 +100,9 @@ impl Parser { break; } } + self.inconfidence += expected.len(); Expect { text: result, - len: expected.len(), parser: self, } } @@ -100,14 +110,13 @@ impl Parser { pub fn expect_ident(&mut self) -> Expect { self.skip_whitespace(); let mut ident: Option = None; - let mut len = 0; while { - if let Some(peek) = self.peek(len) { + if let Some(peek) = self.peek(self.inconfidence) { let lowercase = &peek.to_ascii_lowercase(); if let Some(id) = &mut ident { if ALLOWED_IDENT_CHARS.contains(lowercase) { id.push(peek); - len += 1; + self.inconfidence += 1; true } else { false @@ -115,7 +124,7 @@ impl Parser { } else { if ALLOWED_IDENT_BEGIN_CHARS.contains(lowercase) { ident = Some(peek.to_string()); - len += 1; + self.inconfidence += 1; true } else { false @@ -127,7 +136,6 @@ impl Parser { } {} Expect { text: ident, - len: len, parser: self, } } @@ -135,22 +143,21 @@ impl Parser { pub fn expect_string_lit(&mut self) -> Expect { self.skip_whitespace(); let mut content: Option = None; - let mut len = 0; while { - if let Some(peek) = self.peek(len) { + if let Some(peek) = self.peek(self.inconfidence) { if let Some(cont) = &mut content { if peek == '"' { - len += 1; + self.inconfidence += 1; false } else { cont.push(peek); - len += 1; + self.inconfidence += 1; true } } else { if peek == '"' { content = Some(String::new()); - len += 1; + self.inconfidence += 1; true } else { false @@ -162,12 +169,11 @@ impl Parser { } {} Expect { text: content, - len: len, parser: self, } } - pub fn move_cursor(&mut self) { + pub fn advance_cursor(&mut self) { let curr = self.peek(0).unwrap(); self.cursor += 1; self.character_number += 1; @@ -177,9 +183,9 @@ impl Parser { } } - pub fn move_cursor_multiple(&mut self, amount: usize) { + pub fn advance_cursor_multiple(&mut self, amount: usize) { for _ in 0..amount { - self.move_cursor(); + self.advance_cursor(); } } @@ -187,36 +193,102 @@ impl Parser { Position(self.line_number, self.character_number) } - fn skip_whitespace(&mut self) { + fn skip_whitespace_confident(&mut self, confident: bool) { let mut next = ' '; while self.remaining() > 0 && { - next = self.peek(0).unwrap(); + next = self.peek(self.inconfidence).unwrap(); next == ' ' || next == '\n' || next == '\r' || next == '\t' } { - self.move_cursor(); + if confident { + self.advance_cursor(); + } else { + self.inconfidence += 1; + } } } + fn skip_whitespace(&mut self) { + self.skip_whitespace_confident(false); + } +} + +pub enum Expectable> { + Static(T), + Ident, + StringLit, } pub struct Expect<'a> { text: Option, - len: usize, parser: &'a mut Parser, } -impl Expect<'_> { - pub fn get(self) -> Option { - if self.text.is_some() { - self.parser.move_cursor_multiple(self.len); - } +impl<'a> Expect<'a> { + pub fn get_inconfident(self) -> Option { self.text } + + pub fn get(self) -> Option { + if self.text.is_some() { + self.parser + .advance_cursor_multiple(self.parser.inconfidence); + } + self.parser.inconfidence = 0; + self.text + } + pub fn get_or(self, error: SyntaxError) -> Result { match self.get() { Some(text) => Ok(text), None => Err(error), } } + + pub fn and<'b, T: Into>(self, other: Expectable) -> Expects<'a> { + let texts = if let Some(text) = self.text { + Some(vec![text]) + } else { + None + }; + Expects::and( + Expects { + texts: texts, + parser: self.parser, + }, + other, + ) + } + + fn get_expect>(&mut self, expectable: Expectable) -> Expect { + self.parser.expect(expectable) + } +} + +pub struct Expects<'a> { + texts: Option>, + parser: &'a mut Parser, +} + +impl<'a> Expects<'a> { + pub fn and<'b, T: Into>(mut self, expect: Expectable) -> Expects<'a> { + let other = self.parser.expect(expect); + if let Some(texts) = &mut self.texts { + if let Some(text) = other.get_inconfident() { + texts.push(text); + } else { + self.texts = None; + } + } + self + } + + pub fn get(self) -> Option> { + if self.texts.is_some() { + self.parser + .advance_cursor_multiple(self.parser.inconfidence); + } + self.parser.inconfidence = 0; + self.texts + } } #[derive(Debug, Copy, Clone)] diff --git a/src/parser/parsed_reid.rs b/src/parser/parsed_reid.rs index a0e2d8e..d8f8021 100644 --- a/src/parser/parsed_reid.rs +++ b/src/parser/parsed_reid.rs @@ -1,4 +1,4 @@ -use super::{Parser, Position, SyntaxError}; +use super::{Expectable, Parser, Position, SyntaxError}; type Ident = String; @@ -15,17 +15,17 @@ impl Statement { pub fn parse(parser: &mut Parser) -> Result { let pos = parser.pos(); - if let Some(_) = parser.expect("let").get() { + if let Some(_) = parser.expect_static("let").get() { let ident = parser .expect_ident() .get_or(SyntaxError::ExpectedIdent(pos))?; parser - .expect("=") + .expect_static("=") .get_or(SyntaxError::ExpectedToken(pos, '='))?; match Expression::parse(parser) { Ok(expr) => { parser - .expect(";") + .expect_static(";") .get_or(SyntaxError::ExpectedToken(pos, ';'))?; Ok(Statement::LetStatement(pos, ident, Box::new(expr))) } @@ -36,7 +36,7 @@ impl Statement { Ok(expr) => { let statement = Statement::ExprStatement(pos, expr); parser - .expect(";") + .expect_static(";") .get_or(SyntaxError::ExpectedToken(pos, ';'))?; Ok(statement) } @@ -49,6 +49,7 @@ impl Statement { #[derive(Debug, Clone)] pub enum Expression { BlockExpr(Position, Vec), + FunctionCall(Position, Ident, Vec), ValueRef(Position, Pattern), } @@ -56,8 +57,7 @@ impl Expression { pub fn parse(parser: &mut Parser) -> Result { let begin_pos = parser.pos(); - let expect = parser.expect("{"); - if let Some(_) = expect.get() { + if let Some(_) = parser.expect_static("{").get() { let mut statement_list = Vec::new(); while { match Statement::parse(parser) { @@ -68,11 +68,38 @@ impl Expression { Err(_) => false, } } {} - if let Some(_) = parser.expect("}").get() { + if let Some(_) = parser.expect_static("}").get() { Ok(Expression::BlockExpr(begin_pos, statement_list)) } else { Err(SyntaxError::ExpectedToken(parser.pos(), '}')) } + } else if let Some(texts) = parser.expect_ident().and(Expectable::Static("(")).get() { + let name = texts.get(0).unwrap(); + let mut arg_list = Vec::new(); + while { + match Expression::parse(parser) { + Ok(exp) => { + arg_list.push(exp); + if let Some(_) = parser.expect_static(",").get() { + true + } else { + false + } + } + Err(err) => { + if arg_list.is_empty() { + false + } else { + return Err(err); + } + } + } + } {} + let pos = parser.pos(); + parser + .expect_static(")") + .get_or(SyntaxError::ExpectedToken(pos, ')'))?; + Ok(Expression::FunctionCall(pos, name.clone(), arg_list)) } else if let Ok(pattern) = Pattern::parse(parser) { Ok(Expression::ValueRef(begin_pos, pattern)) } else {