Add support for i32 variable type
This commit is contained in:
parent
8b60677123
commit
8028dde855
@ -1,3 +1 @@
|
|||||||
let otus = "Hello, world!";
|
let gotus = 3;
|
||||||
let dotus = otus;
|
|
||||||
print(dotus);
|
|
@ -1,4 +1,5 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::num::ParseIntError;
|
||||||
|
|
||||||
use super::errors::CompilerError;
|
use super::errors::CompilerError;
|
||||||
use super::parser::{Expression, LiteralPattern, ParsedReid, Pattern, Position, Statement};
|
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
|
AssignVariable(HeapID, RegID), // Assign variable from registery at RegID
|
||||||
VarToReg(HeapID, RegID), // Bring Variable to registery at RegID
|
VarToReg(HeapID, RegID), // Bring Variable to registery at RegID
|
||||||
StringLit(String), // Bring String Literal to Stack
|
StringLit(String), // Bring String Literal to Stack
|
||||||
|
I32Lit(i32), // Bring i32 Literal to Stack
|
||||||
FunctionCall(FuncID), // Call Function at FuncID
|
FunctionCall(FuncID), // Call Function at FuncID
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,10 +147,25 @@ impl Compiler {
|
|||||||
|
|
||||||
fn handle_literal(&mut self, pattern: LiteralPattern) -> Result<VariableType, CompilerError> {
|
fn handle_literal(&mut self, pattern: LiteralPattern) -> Result<VariableType, CompilerError> {
|
||||||
match pattern {
|
match pattern {
|
||||||
LiteralPattern::StringLit(string) => self.list.push(Command::StringLit(string)),
|
LiteralPattern::StringLit(string) => {
|
||||||
}
|
self.list.push(Command::StringLit(string));
|
||||||
Ok(VariableType::TypeString)
|
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)),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -2,6 +2,7 @@ use super::parser::Position;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::num::ParseIntError;
|
||||||
|
|
||||||
use super::vm::VariableType;
|
use super::vm::VariableType;
|
||||||
|
|
||||||
@ -67,6 +68,7 @@ pub enum CompilerError {
|
|||||||
LetFailed(Position, Box<CompilerError>),
|
LetFailed(Position, Box<CompilerError>),
|
||||||
CanNotAssignVoidType,
|
CanNotAssignVoidType,
|
||||||
FunctionNotFound(Position, String, Vec<VariableType>),
|
FunctionNotFound(Position, String, Vec<VariableType>),
|
||||||
|
ParseIntError(ParseIntError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompilerError {
|
impl CompilerError {
|
||||||
@ -102,6 +104,7 @@ impl Display for CompilerError {
|
|||||||
ParamList(params.clone()),
|
ParamList(params.clone()),
|
||||||
pos
|
pos
|
||||||
),
|
),
|
||||||
|
CompilerError::ParseIntError(err) => format!("Failed to parse integer value: {}", err),
|
||||||
};
|
};
|
||||||
write!(f, "{}", text)
|
write!(f, "{}", text)
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,15 @@ fn main() {
|
|||||||
eprintln!("Syntax error: {}", error);
|
eprintln!("Syntax error: {}", error);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
//dbg!(&parsed);
|
dbg!(&parsed);
|
||||||
|
|
||||||
let print = BuiltinFunctionDef::new(
|
let print = BuiltinFunctionDef::new(
|
||||||
"print",
|
"print",
|
||||||
vec![VariableType::TypeString],
|
vec![VariableType::TypeString],
|
||||||
Box::new(move |args| {
|
Box::new(move |args| {
|
||||||
let Value::StringVal(string) = &args[0];
|
if let Value::StringVal(string) = &args[0] {
|
||||||
println!("{}", string);
|
println!("{}", string);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
let builtin_functions = BuiltinFunctions(vec![print]);
|
let builtin_functions = BuiltinFunctions(vec![print]);
|
||||||
@ -39,7 +40,7 @@ fn main() {
|
|||||||
eprintln!("Compilation error: {}", error);
|
eprintln!("Compilation error: {}", error);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
//dbg!(&compiled);
|
dbg!(&compiled);
|
||||||
|
|
||||||
let mut vm = VirtualMachine::from(compiled.unwrap());
|
let mut vm = VirtualMachine::from(compiled.unwrap());
|
||||||
vm.add_builtin_functions(builtin_functions);
|
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',
|
'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',
|
'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 {
|
pub struct Parser {
|
||||||
text: Vec<char>,
|
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) {
|
pub fn advance_cursor(&mut self) {
|
||||||
let curr = self.peek(0).unwrap();
|
let curr = self.peek(0).unwrap();
|
||||||
self.cursor += 1;
|
self.cursor += 1;
|
||||||
|
@ -122,6 +122,11 @@ impl Pattern {
|
|||||||
pos,
|
pos,
|
||||||
LiteralPattern::StringLit(string),
|
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() {
|
} else if let Some(ident) = parser.expect_ident().get() {
|
||||||
Ok(Pattern::IdentPattern(pos, ident))
|
Ok(Pattern::IdentPattern(pos, ident))
|
||||||
} else {
|
} else {
|
||||||
@ -133,4 +138,5 @@ impl Pattern {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum LiteralPattern {
|
pub enum LiteralPattern {
|
||||||
StringLit(String),
|
StringLit(String),
|
||||||
|
Integer32Lit(String),
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,14 @@ impl VirtualMachine {
|
|||||||
Err(RuntimePanic::StackOverflow)
|
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) => {
|
Command::FunctionCall(funcid) => {
|
||||||
if self.functions.len() <= funcid {
|
if self.functions.len() <= funcid {
|
||||||
Err(RuntimePanic::InvalidFuncAddress)
|
Err(RuntimePanic::InvalidFuncAddress)
|
||||||
@ -194,12 +202,14 @@ impl AllocatedVar {
|
|||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
StringVal(String),
|
StringVal(String),
|
||||||
|
I32Val(i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
fn get_type(&self) -> VariableType {
|
fn get_type(&self) -> VariableType {
|
||||||
match self {
|
match self {
|
||||||
Value::StringVal(_) => VariableType::TypeString,
|
Value::StringVal(_) => VariableType::TypeString,
|
||||||
|
Value::I32Val(_) => VariableType::TypeI32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,12 +217,14 @@ impl Value {
|
|||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum VariableType {
|
pub enum VariableType {
|
||||||
TypeString,
|
TypeString,
|
||||||
|
TypeI32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for VariableType {
|
impl ToString for VariableType {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
VariableType::TypeString => "String".to_string(),
|
VariableType::TypeString => "String".to_string(),
|
||||||
|
VariableType::TypeI32 => "i32".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user