added let, about to add types

This commit is contained in:
Andrew Segavac
2021-04-18 08:51:21 -06:00
parent facead092f
commit 4446d0f297
11 changed files with 438 additions and 216 deletions

View File

@@ -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>,
}

View File

@@ -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 = {

View File

@@ -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,

View File

@@ -1,3 +1,4 @@
mod types;
mod ast;
#[macro_use] extern crate lalrpop_util;

74
src/type_checker.rs Normal file
View 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
View 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