static typing

This commit is contained in:
tezlm 2023-05-10 02:02:53 -07:00
parent 924e7e2781
commit 353b556734
Signed by: tezlm
GPG key ID: 649733FCD94AFBBA
2 changed files with 58 additions and 13 deletions

View file

@ -50,6 +50,16 @@ pub enum Data {
Array(Vec<Data>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DataType {
Unsigned,
Integer,
Float,
String,
Boolean,
Array(Box<DataType>),
}
#[derive(Debug)]
pub enum BinaryOperation {
Add, Subtract, Multiply, Divide,
@ -67,18 +77,28 @@ pub struct Compiler {
registers: [bool; 256],
}
fn get_binary_type(operation: &BinaryOperation, data_type_left: &DataType, data_type_right: &DataType) -> DataType {
use BinaryOperation::*;
match (operation, data_type_left, data_type_right) {
(Add | Subtract | Multiply | Divide, DataType::Float, DataType::Float) => DataType::Float,
(In, item, DataType::Array(generic)) if item == generic.as_ref() => DataType::Boolean,
(Add, DataType::String, DataType::String) => DataType::String,
_ => panic!("invalid types"),
}
}
impl Compiler {
fn tree(&mut self, tree: &parser::Tree) -> Register {
fn tree(&mut self, tree: &parser::Tree) -> (DataType, Register) {
match tree {
parser::Tree::Value { term, kind } => {
use crate::lexer::TokenType;
let data = match kind {
let (data_type, data) = match kind {
TokenType::Float => {
let float: f64 = term.parse().unwrap();
Data::Float(float)
(DataType::Float, Data::Float(float))
},
TokenType::String => {
Data::String(term[1..term.len() - 1].to_string())
(DataType::String, Data::String(term[1..term.len() - 1].to_string()))
},
_ => todo!(),
};
@ -88,10 +108,10 @@ impl Compiler {
input: idx,
dest: reg,
});
reg
(data_type, reg)
},
parser::Tree::Unary { op, term } => {
let reg_input = self.tree(term);
let (data_type, reg_input) = self.tree(term);
let reg_dest = self.next_register();
let operator = match op.as_str() {
"-" => UnaryOperation::Negate,
@ -102,11 +122,11 @@ impl Compiler {
input: reg_input,
dest: reg_dest,
});
reg_dest
(data_type, reg_dest)
},
parser::Tree::Binary { op, left, right } => {
let reg_left = self.tree(left);
let reg_right = self.tree(right);
let (data_type_left, reg_left) = self.tree(left);
let (data_type_right, reg_right) = self.tree(right);
let reg_dest = self.next_register();
let operator = match op.as_str() {
"+" => BinaryOperation::Add,
@ -116,26 +136,31 @@ impl Compiler {
"in" => BinaryOperation::In,
_ => todo!(),
};
let data_type = get_binary_type(&operator, &data_type_left, &data_type_right);
self.code.push(Instruction::BinaryOperator {
operator,
left: reg_left,
right: reg_right,
dest: reg_dest,
});
reg_dest
(data_type, reg_dest)
},
parser::Tree::Array { terms } => {
// TODO: 0 length arrays
let reg = self.next_register();
let mut array_kind = None;
self.code.push(Instruction::Array { dest: reg });
for term in terms {
let reg_term = self.tree(term);
let (kind, reg_term) = self.tree(term);
if *array_kind.get_or_insert_with(|| kind.clone()) != kind {
panic!("nope");
}
self.code.push(Instruction::ArrayAppend {
source: reg_term,
dest: reg,
});
}
reg
(DataType::Array(Box::new(array_kind.unwrap())), reg)
},
unknown => todo!("unknown token {:?}", unknown),
}
@ -166,11 +191,12 @@ pub fn expr(tree: &parser::Tree) -> Bytecode {
data: Vec::new(),
registers: [false; 256],
};
let reg = compiler.tree(tree);
let (data_type, reg) = compiler.tree(tree);
let mut bytecode = Bytecode {
code: compiler.code,
data: compiler.data,
};
dbg!(data_type);
bytecode.code.push(Instruction::Return { source: reg });
bytecode
}

19
src/types.rs Normal file
View file

@ -0,0 +1,19 @@
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
Unsigned(u64),
Integer(i64),
Float(f64),
String(String),
Boolean(bool),
Array(Vec<Data>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum ValueType {
Unsigned,
Integer,
Float,
String,
Boolean,
Array(Box<DataType>),
}