added let, about to add types
This commit is contained in:
38
src/ast.rs
38
src/ast.rs
@@ -1,23 +1,27 @@
|
||||
use crate::types;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Span {
|
||||
pub left: usize,
|
||||
pub right: usize
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Spanned<T> {
|
||||
pub span: Span,
|
||||
pub value: T,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TypeUsage {
|
||||
pub name: Spanned<Identifier>
|
||||
pub name: Spanned<Identifier>,
|
||||
pub ty: types::SpecifiedType,
|
||||
//TODO: Generics go here
|
||||
// mut, weak here
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Operator {
|
||||
Mul,
|
||||
Div,
|
||||
@@ -25,30 +29,30 @@ pub enum Operator {
|
||||
Minus,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct LiteralInt {
|
||||
pub value: i64,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Identifier {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct FunctionCall {
|
||||
pub name: Spanned<Identifier>,
|
||||
pub arguments: Vec<Spanned<Box<Expression>>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Operation {
|
||||
pub left: Spanned<Box<Expression>>,
|
||||
pub op: Operator,
|
||||
pub right: Spanned<Box<Expression>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Expression {
|
||||
LiteralInt(Spanned<LiteralInt>),
|
||||
FunctionCall(Spanned<FunctionCall>),
|
||||
@@ -56,32 +60,32 @@ pub enum Expression {
|
||||
Op(Operation),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Assignment {
|
||||
pub name: Spanned<Identifier>,
|
||||
pub type_usage: Option<Spanned<TypeUsage>>,
|
||||
// mut, weak here
|
||||
// mut, weak here if type not used
|
||||
pub expression: Spanned<Box<Expression>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Statement {
|
||||
Assignment(Spanned<Assignment>),
|
||||
Expression(Spanned<Box<Expression>>),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Block {
|
||||
pub statements: Vec<Spanned<Statement>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct VariableDeclaration {
|
||||
pub name: Spanned<Identifier>,
|
||||
pub type_usage: Spanned<TypeUsage>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Function {
|
||||
pub name: Spanned<Identifier>,
|
||||
pub arguments: Vec<VariableDeclaration>,
|
||||
@@ -90,7 +94,7 @@ pub struct Function {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Module {
|
||||
pub functions: Vec<Function>,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::str::FromStr;
|
||||
use crate::ast;
|
||||
|
||||
use crate::types;
|
||||
|
||||
grammar;
|
||||
|
||||
@@ -53,7 +53,7 @@ pub Block: ast::Block = {
|
||||
}
|
||||
|
||||
pub TypeUsage: ast::TypeUsage = {
|
||||
<n:Spanned<Identifier>> => ast::TypeUsage{name: n}
|
||||
<n:Spanned<Identifier>> => ast::TypeUsage{name: n, ty: types::SpecifiedType::Unknown}
|
||||
}
|
||||
|
||||
pub VariableDeclaration: ast::VariableDeclaration = {
|
||||
|
||||
@@ -3,6 +3,7 @@ use inkwell::context::Context;
|
||||
use crate::ast;
|
||||
use crate::hir:errors;
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub enum Signedness {
|
||||
Signed,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
mod types;
|
||||
mod ast;
|
||||
#[macro_use] extern crate lalrpop_util;
|
||||
|
||||
|
||||
74
src/type_checker.rs
Normal file
74
src/type_checker.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::types;
|
||||
use crate::ast;
|
||||
|
||||
|
||||
|
||||
pub struct TypeChecker {}
|
||||
|
||||
|
||||
impl TypeChecker {
|
||||
pub fn check_module(&self, types_defs: HashMap<String, types::Type>, module: &mut ast::Module) -> Result<bool> {
|
||||
let mut update = false;
|
||||
for function in module.functions {
|
||||
let update_here = self.check_function(&mut function)?;
|
||||
if update_here {
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
return update;
|
||||
}
|
||||
|
||||
pub fn check_function(&self, function: &mut ast::Function) -> Result<bool> {
|
||||
let mut update = false;
|
||||
for argument in function.arguments {
|
||||
let update_here = self.check_variable_declaration(argument)?;
|
||||
if update_here {
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
let update_here = self.check_variable_declaration(function.return_type)?;
|
||||
if update_here {
|
||||
update = true;
|
||||
}
|
||||
let update_here = self.check_block(function.block)?;
|
||||
return update;
|
||||
}
|
||||
|
||||
pub fn check_variable_declaration(&self, declaration: &mut ast::Spanned<ast::VariableDeclaration>) -> Result<bool> {
|
||||
return self.check_type_usage(&self, declaration.value.type_usage)?;
|
||||
}
|
||||
|
||||
pub fn check_type_usage(&self, usage: &mut ast::Spanned<ast::TypeUsage>) {
|
||||
match usage.value.identifier.value.name {
|
||||
"Int8" => {
|
||||
let def = IntTypeDef{
|
||||
signedness: types::Signedness::Signed,
|
||||
bitness: types::IntBitness::X8,
|
||||
}
|
||||
usage.ty = types::SpecifiedType::Type(types::Type::Int(def))
|
||||
},
|
||||
"Int16" => {
|
||||
let def = IntTypeDef{
|
||||
signedness: types::Signedness::Signed,
|
||||
bitness: types::IntBitness::X16,
|
||||
}
|
||||
usage.ty = types::SpecifiedType::Type(types::Type::Int(def))
|
||||
},
|
||||
"Int32" => {
|
||||
let def = IntTypeDef{
|
||||
signedness: types::Signedness::Signed,
|
||||
bitness: types::IntBitness::X32,
|
||||
}
|
||||
usage.ty = types::SpecifiedType::Type(types::Type::Int(def))
|
||||
},
|
||||
"Int64" => {
|
||||
let def = IntTypeDef{
|
||||
signedness: types::Signedness::Signed,
|
||||
bitness: types::IntBitness::X32,
|
||||
}
|
||||
usage.ty = types::SpecifiedType::Type(types::Type::Int(def))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
75
src/types.rs
Normal file
75
src/types.rs
Normal file
@@ -0,0 +1,75 @@
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub enum Signedness {
|
||||
Signed,
|
||||
Unsigned,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub enum IntBitness {
|
||||
X8,
|
||||
X16,
|
||||
X32,
|
||||
X64,
|
||||
X128,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub enum FloatBitness {
|
||||
X32,
|
||||
X64,
|
||||
X128,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
pub struct IntTypeDef {
|
||||
pub signedness: Signedness,
|
||||
pub bitness: IntBitness,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct FloatTypeDef {
|
||||
pub bitness: FloatBitness,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct FunctionTypeDef {
|
||||
pub arguments: Vec<Type>,
|
||||
pub return_type: Box<Type>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Type {
|
||||
Bool,
|
||||
Int(IntTypeDef),
|
||||
Float(FloatTypeDef),
|
||||
Function(FunctionTypeDef),
|
||||
// String(StringTypeDef),
|
||||
// Struct(StructTypeDef),
|
||||
// Trait(TraitTypeDef),
|
||||
// Void,
|
||||
// Never,
|
||||
}
|
||||
|
||||
|
||||
/// Used for places where type info may or may not be solved.
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
pub enum SpecifiedType {
|
||||
Unknown,
|
||||
Type(Type),
|
||||
}
|
||||
|
||||
|
||||
// Env table
|
||||
// name => ast_id
|
||||
//
|
||||
// Type Table
|
||||
// ast_id => type_id
|
||||
//
|
||||
//
|
||||
// TypeDef Table
|
||||
// type_id => type_def
|
||||
Reference in New Issue
Block a user