static typing
This commit is contained in:
parent
924e7e2781
commit
353b556734
2 changed files with 58 additions and 13 deletions
|
@ -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
19
src/types.rs
Normal 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>),
|
||||
}
|
Loading…
Reference in a new issue