From 8028dde855fd3e897ca3b60b7eb0e640e1323a8d Mon Sep 17 00:00:00 2001 From: Teascade Date: Thu, 25 Jun 2020 00:39:18 +0300 Subject: [PATCH] Add support for i32 variable type --- reid_src/test.reid | 4 +--- src/compiler.rs | 21 +++++++++++++++++++-- src/errors.rs | 3 +++ src/main.rs | 9 +++++---- src/parser/mod.rs | 28 ++++++++++++++++++++++++++++ src/parser/parsed_reid.rs | 6 ++++++ src/vm/mod.rs | 12 ++++++++++++ 7 files changed, 74 insertions(+), 9 deletions(-) diff --git a/reid_src/test.reid b/reid_src/test.reid index 5fbe3b8..971ff3f 100644 --- a/reid_src/test.reid +++ b/reid_src/test.reid @@ -1,3 +1 @@ -let otus = "Hello, world!"; -let dotus = otus; -print(dotus); \ No newline at end of file +let gotus = 3; \ No newline at end of file diff --git a/src/compiler.rs b/src/compiler.rs index 0e3e5d1..d89bb5c 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::num::ParseIntError; use super::errors::CompilerError; use super::parser::{Expression, LiteralPattern, ParsedReid, Pattern, Position, Statement}; @@ -19,6 +20,7 @@ pub enum Command { AssignVariable(HeapID, RegID), // Assign variable from registery at RegID VarToReg(HeapID, RegID), // Bring Variable to registery at RegID StringLit(String), // Bring String Literal to Stack + I32Lit(i32), // Bring i32 Literal to Stack FunctionCall(FuncID), // Call Function at FuncID } @@ -145,9 +147,24 @@ impl Compiler { fn handle_literal(&mut self, pattern: LiteralPattern) -> Result { match pattern { - LiteralPattern::StringLit(string) => self.list.push(Command::StringLit(string)), + LiteralPattern::StringLit(string) => { + self.list.push(Command::StringLit(string)); + Ok(VariableType::TypeString) + } + LiteralPattern::Integer32Lit(string) => { + self.list.push(Command::I32Lit(Compiler::handle_parseint( + string.parse::(), + )?)); + Ok(VariableType::TypeI32) + } + } + } + + fn handle_parseint(res: Result) -> Result { + match res { + Ok(i) => Ok(i), + Err(err) => Err(CompilerError::ParseIntError(err)), } - Ok(VariableType::TypeString) } } diff --git a/src/errors.rs b/src/errors.rs index 339971e..7fd999c 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -2,6 +2,7 @@ use super::parser::Position; use std::fmt; use std::fmt::Display; use std::io; +use std::num::ParseIntError; use super::vm::VariableType; @@ -67,6 +68,7 @@ pub enum CompilerError { LetFailed(Position, Box), CanNotAssignVoidType, FunctionNotFound(Position, String, Vec), + ParseIntError(ParseIntError), } impl CompilerError { @@ -102,6 +104,7 @@ impl Display for CompilerError { ParamList(params.clone()), pos ), + CompilerError::ParseIntError(err) => format!("Failed to parse integer value: {}", err), }; write!(f, "{}", text) } diff --git a/src/main.rs b/src/main.rs index 278d6d6..533bf05 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,14 +20,15 @@ fn main() { eprintln!("Syntax error: {}", error); std::process::exit(1); } - //dbg!(&parsed); + dbg!(&parsed); let print = BuiltinFunctionDef::new( "print", vec![VariableType::TypeString], Box::new(move |args| { - let Value::StringVal(string) = &args[0]; - println!("{}", string); + if let Value::StringVal(string) = &args[0] { + println!("{}", string); + } }), ); let builtin_functions = BuiltinFunctions(vec![print]); @@ -39,7 +40,7 @@ fn main() { eprintln!("Compilation error: {}", error); std::process::exit(1); } - //dbg!(&compiled); + dbg!(&compiled); let mut vm = VirtualMachine::from(compiled.unwrap()); vm.add_builtin_functions(builtin_functions); diff --git a/src/parser/mod.rs b/src/parser/mod.rs index eb09bd3..edf9ccc 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -13,6 +13,7 @@ const ALLOWED_IDENT_BEGIN_CHARS: [char; 26] = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ]; +const ALLOWED_NUMERALS: [char; 10] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; pub struct Parser { text: Vec, @@ -173,6 +174,33 @@ impl Parser { } } + pub fn expect_numeral_lit(&mut self) -> Expect { + self.skip_whitespace(); + let mut content: Option = None; + while { + if let Some(peek) = self.peek(self.inconfidence) { + if ALLOWED_NUMERALS.contains(&peek) { + let mut string = match content { + Some(s) => s, + None => String::new(), + }; + string.push(peek); + content = Some(string); + self.inconfidence += 1; + true + } else { + false + } + } else { + false + } + } {} + Expect { + text: content, + parser: self, + } + } + pub fn advance_cursor(&mut self) { let curr = self.peek(0).unwrap(); self.cursor += 1; diff --git a/src/parser/parsed_reid.rs b/src/parser/parsed_reid.rs index ebd897e..29d6e03 100644 --- a/src/parser/parsed_reid.rs +++ b/src/parser/parsed_reid.rs @@ -122,6 +122,11 @@ impl Pattern { pos, LiteralPattern::StringLit(string), )) + } else if let Some(int) = parser.expect_numeral_lit().get() { + Ok(Pattern::LiteralPattern( + pos, + LiteralPattern::Integer32Lit(int), + )) } else if let Some(ident) = parser.expect_ident().get() { Ok(Pattern::IdentPattern(pos, ident)) } else { @@ -133,4 +138,5 @@ impl Pattern { #[derive(Debug, Clone)] pub enum LiteralPattern { StringLit(String), + Integer32Lit(String), } diff --git a/src/vm/mod.rs b/src/vm/mod.rs index 91d1fca..d917a7a 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -149,6 +149,14 @@ impl VirtualMachine { Err(RuntimePanic::StackOverflow) } } + Command::I32Lit(val) => { + if self.stack.len() < usize::MAX { + self.stack.push(Value::I32Val(val)); + Ok(()) + } else { + Err(RuntimePanic::StackOverflow) + } + } Command::FunctionCall(funcid) => { if self.functions.len() <= funcid { Err(RuntimePanic::InvalidFuncAddress) @@ -194,12 +202,14 @@ impl AllocatedVar { #[derive(Clone, Debug, PartialEq, Eq)] pub enum Value { StringVal(String), + I32Val(i32), } impl Value { fn get_type(&self) -> VariableType { match self { Value::StringVal(_) => VariableType::TypeString, + Value::I32Val(_) => VariableType::TypeI32, } } } @@ -207,12 +217,14 @@ impl Value { #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum VariableType { TypeString, + TypeI32, } impl ToString for VariableType { fn to_string(&self) -> String { match self { VariableType::TypeString => "String".to_string(), + VariableType::TypeI32 => "i32".to_string(), } } }