Add support for i32 variable type
This commit is contained in:
		
							parent
							
								
									8b60677123
								
							
						
					
					
						commit
						8028dde855
					
				| @ -1,3 +1 @@ | ||||
| let otus = "Hello, world!"; | ||||
| let dotus = otus; | ||||
| print(dotus); | ||||
| let gotus = 3; | ||||
| @ -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<VariableType, CompilerError> { | ||||
|         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::<i32>(), | ||||
|                 )?)); | ||||
|                 Ok(VariableType::TypeI32) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn handle_parseint<T>(res: Result<T, ParseIntError>) -> Result<T, CompilerError> { | ||||
|         match res { | ||||
|             Ok(i) => Ok(i), | ||||
|             Err(err) => Err(CompilerError::ParseIntError(err)), | ||||
|         } | ||||
|         Ok(VariableType::TypeString) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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<CompilerError>), | ||||
|     CanNotAssignVoidType, | ||||
|     FunctionNotFound(Position, String, Vec<VariableType>), | ||||
|     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) | ||||
|     } | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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<char>, | ||||
| @ -173,6 +174,33 @@ impl Parser { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn expect_numeral_lit(&mut self) -> Expect { | ||||
|         self.skip_whitespace(); | ||||
|         let mut content: Option<String> = 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; | ||||
|  | ||||
| @ -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), | ||||
| } | ||||
|  | ||||
| @ -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(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user