Move minimal typechecking code into directory-style module
This commit is contained in:
parent
4dd39fe085
commit
08590430e4
@ -1,128 +1,130 @@
|
||||
use std::str::FromStr;
|
||||
use std::convert::TryFrom;
|
||||
use std::{convert::TryFrom, str::FromStr};
|
||||
|
||||
use crate::typechecking::{TypeConst, Type};
|
||||
use crate::ast::{BinOp, PrefixOp};
|
||||
use crate::{
|
||||
ast::{BinOp, PrefixOp},
|
||||
type_inference::Type,
|
||||
};
|
||||
|
||||
/// "Builtin" computational operations with some kind of semantics, mostly mathematical operations.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Builtin {
|
||||
Add,
|
||||
Increment,
|
||||
Subtract,
|
||||
Negate,
|
||||
Multiply,
|
||||
Divide,
|
||||
Quotient,
|
||||
Modulo,
|
||||
Exponentiation,
|
||||
BitwiseAnd,
|
||||
BitwiseOr,
|
||||
BooleanAnd,
|
||||
BooleanOr,
|
||||
BooleanNot,
|
||||
Equality,
|
||||
LessThan,
|
||||
LessThanOrEqual,
|
||||
GreaterThan,
|
||||
GreaterThanOrEqual,
|
||||
Comparison,
|
||||
FieldAccess,
|
||||
IOPrint,
|
||||
IOPrintLn,
|
||||
IOGetLine,
|
||||
Assignment,
|
||||
Concatenate,
|
||||
Add,
|
||||
Increment,
|
||||
Subtract,
|
||||
Negate,
|
||||
Multiply,
|
||||
Divide,
|
||||
Quotient,
|
||||
Modulo,
|
||||
Exponentiation,
|
||||
BitwiseAnd,
|
||||
BitwiseOr,
|
||||
BooleanAnd,
|
||||
BooleanOr,
|
||||
BooleanNot,
|
||||
Equality,
|
||||
LessThan,
|
||||
LessThanOrEqual,
|
||||
GreaterThan,
|
||||
GreaterThanOrEqual,
|
||||
Comparison,
|
||||
FieldAccess,
|
||||
IOPrint,
|
||||
IOPrintLn,
|
||||
IOGetLine,
|
||||
Assignment,
|
||||
Concatenate,
|
||||
}
|
||||
|
||||
impl Builtin {
|
||||
pub fn get_type(&self) -> Type {
|
||||
use Builtin::*;
|
||||
match self {
|
||||
Add => ty!(Nat -> Nat -> Nat),
|
||||
Subtract => ty!(Nat -> Nat -> Nat),
|
||||
Multiply => ty!(Nat -> Nat -> Nat),
|
||||
Divide => ty!(Nat -> Nat -> Float),
|
||||
Quotient => ty!(Nat -> Nat -> Nat),
|
||||
Modulo => ty!(Nat -> Nat -> Nat),
|
||||
Exponentiation => ty!(Nat -> Nat -> Nat),
|
||||
BitwiseAnd => ty!(Nat -> Nat -> Nat),
|
||||
BitwiseOr => ty!(Nat -> Nat -> Nat),
|
||||
BooleanAnd => ty!(Bool -> Bool -> Bool),
|
||||
BooleanOr => ty!(Bool -> Bool -> Bool),
|
||||
BooleanNot => ty!(Bool -> Bool),
|
||||
Equality => ty!(Nat -> Nat -> Bool),
|
||||
LessThan => ty!(Nat -> Nat -> Bool),
|
||||
LessThanOrEqual => ty!(Nat -> Nat -> Bool),
|
||||
GreaterThan => ty!(Nat -> Nat -> Bool),
|
||||
GreaterThanOrEqual => ty!(Nat -> Nat -> Bool),
|
||||
Comparison => ty!(Nat -> Nat -> Ordering),
|
||||
FieldAccess => ty!(Unit),
|
||||
IOPrint => ty!(Unit),
|
||||
IOPrintLn => ty!(Unit) ,
|
||||
IOGetLine => ty!(StringT),
|
||||
Assignment => ty!(Unit),
|
||||
Concatenate => ty!(StringT -> StringT -> StringT),
|
||||
Increment => ty!(Nat -> Int),
|
||||
Negate => ty!(Nat -> Int)
|
||||
#[allow(dead_code)]
|
||||
pub fn get_type(&self) -> Type {
|
||||
use Builtin::*;
|
||||
match self {
|
||||
Add => ty!(Nat -> Nat -> Nat),
|
||||
Subtract => ty!(Nat -> Nat -> Nat),
|
||||
Multiply => ty!(Nat -> Nat -> Nat),
|
||||
Divide => ty!(Nat -> Nat -> Float),
|
||||
Quotient => ty!(Nat -> Nat -> Nat),
|
||||
Modulo => ty!(Nat -> Nat -> Nat),
|
||||
Exponentiation => ty!(Nat -> Nat -> Nat),
|
||||
BitwiseAnd => ty!(Nat -> Nat -> Nat),
|
||||
BitwiseOr => ty!(Nat -> Nat -> Nat),
|
||||
BooleanAnd => ty!(Bool -> Bool -> Bool),
|
||||
BooleanOr => ty!(Bool -> Bool -> Bool),
|
||||
BooleanNot => ty!(Bool -> Bool),
|
||||
Equality => ty!(Nat -> Nat -> Bool),
|
||||
LessThan => ty!(Nat -> Nat -> Bool),
|
||||
LessThanOrEqual => ty!(Nat -> Nat -> Bool),
|
||||
GreaterThan => ty!(Nat -> Nat -> Bool),
|
||||
GreaterThanOrEqual => ty!(Nat -> Nat -> Bool),
|
||||
Comparison => ty!(Nat -> Nat -> Ordering),
|
||||
FieldAccess => ty!(Unit),
|
||||
IOPrint => ty!(Unit),
|
||||
IOPrintLn => ty!(Unit),
|
||||
IOGetLine => ty!(StringT),
|
||||
Assignment => ty!(Unit),
|
||||
Concatenate => ty!(StringT -> StringT -> StringT),
|
||||
Increment => ty!(Nat -> Int),
|
||||
Negate => ty!(Nat -> Int),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&BinOp> for Builtin {
|
||||
type Error = ();
|
||||
type Error = ();
|
||||
|
||||
fn try_from(binop: &BinOp) -> Result<Self, Self::Error> {
|
||||
FromStr::from_str(binop.sigil())
|
||||
}
|
||||
fn try_from(binop: &BinOp) -> Result<Self, Self::Error> {
|
||||
FromStr::from_str(binop.sigil())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&PrefixOp> for Builtin {
|
||||
type Error = ();
|
||||
type Error = ();
|
||||
|
||||
fn try_from(prefix_op: &PrefixOp) -> Result<Self, Self::Error> {
|
||||
use Builtin::*;
|
||||
fn try_from(prefix_op: &PrefixOp) -> Result<Self, Self::Error> {
|
||||
use Builtin::*;
|
||||
|
||||
match prefix_op.sigil() {
|
||||
"+" => Ok(Increment),
|
||||
"-" => Ok(Negate),
|
||||
"!" => Ok(BooleanNot),
|
||||
_ => Err(())
|
||||
match prefix_op.sigil() {
|
||||
"+" => Ok(Increment),
|
||||
"-" => Ok(Negate),
|
||||
"!" => Ok(BooleanNot),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Builtin {
|
||||
type Err = ();
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
use Builtin::*;
|
||||
Ok(match s {
|
||||
"+" => Add,
|
||||
"-" => Subtract,
|
||||
"*" => Multiply,
|
||||
"/" => Divide,
|
||||
"quot" => Quotient,
|
||||
"%" => Modulo,
|
||||
"++" => Concatenate,
|
||||
"^" => Exponentiation,
|
||||
"&" => BitwiseAnd,
|
||||
"&&" => BooleanAnd,
|
||||
"|" => BitwiseOr,
|
||||
"||" => BooleanOr,
|
||||
"!" => BooleanNot,
|
||||
">" => GreaterThan,
|
||||
">=" => GreaterThanOrEqual,
|
||||
"<" => LessThan,
|
||||
"<=" => LessThanOrEqual,
|
||||
"==" => Equality,
|
||||
"=" => Assignment,
|
||||
"<=>" => Comparison,
|
||||
"." => FieldAccess,
|
||||
"print" => IOPrint,
|
||||
"println" => IOPrintLn,
|
||||
"getline" => IOGetLine,
|
||||
_ => return Err(())
|
||||
})
|
||||
}
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
use Builtin::*;
|
||||
Ok(match s {
|
||||
"+" => Add,
|
||||
"-" => Subtract,
|
||||
"*" => Multiply,
|
||||
"/" => Divide,
|
||||
"quot" => Quotient,
|
||||
"%" => Modulo,
|
||||
"++" => Concatenate,
|
||||
"^" => Exponentiation,
|
||||
"&" => BitwiseAnd,
|
||||
"&&" => BooleanAnd,
|
||||
"|" => BitwiseOr,
|
||||
"||" => BooleanOr,
|
||||
"!" => BooleanNot,
|
||||
">" => GreaterThan,
|
||||
">=" => GreaterThanOrEqual,
|
||||
"<" => LessThan,
|
||||
"<=" => LessThanOrEqual,
|
||||
"==" => Equality,
|
||||
"=" => Assignment,
|
||||
"<=>" => Comparison,
|
||||
"." => FieldAccess,
|
||||
"print" => IOPrint,
|
||||
"println" => IOPrintLn,
|
||||
"getline" => IOGetLine,
|
||||
_ => return Err(()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::parsing::ParseError;
|
||||
use crate::schala::{SourceReference, Stage};
|
||||
use crate::tokenizing::{Location, Token, TokenKind};
|
||||
use crate::symbol_table::SymbolError;
|
||||
use crate::typechecking::TypeError;
|
||||
use crate::type_inference::TypeError;
|
||||
|
||||
pub struct SchalaError {
|
||||
errors: Vec<Error>,
|
||||
@ -19,6 +19,7 @@ impl SchalaError {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn from_type_error(err: TypeError) -> Self {
|
||||
Self {
|
||||
formatted_parse_error: None,
|
||||
|
@ -13,8 +13,9 @@ extern crate derivative;
|
||||
|
||||
#[macro_use]
|
||||
mod util;
|
||||
|
||||
#[macro_use]
|
||||
mod typechecking;
|
||||
mod type_inference;
|
||||
|
||||
mod ast;
|
||||
mod parsing;
|
||||
|
@ -4,7 +4,7 @@ use std::convert::From;
|
||||
|
||||
use crate::builtin::Builtin;
|
||||
use crate::symbol_table::{DefId, SymbolTable};
|
||||
use crate::typechecking::TypeId;
|
||||
use crate::type_inference::TypeId;
|
||||
|
||||
//TODO most of these Clone impls only exist to support function application, because the
|
||||
//tree-walking evaluator moves the reduced IR members.
|
||||
|
@ -5,7 +5,7 @@ use schala_repl::{
|
||||
use stopwatch::Stopwatch;
|
||||
|
||||
use crate::{
|
||||
error::SchalaError, parsing, reduced_ir, symbol_table, tokenizing, tree_walk_eval, typechecking,
|
||||
error::SchalaError, parsing, reduced_ir, symbol_table, tokenizing, tree_walk_eval, type_inference,
|
||||
};
|
||||
|
||||
/// All the state necessary to parse and execute a Schala program are stored in this struct.
|
||||
@ -17,7 +17,7 @@ pub struct Schala<'a> {
|
||||
/// Keeps track of symbols and scopes
|
||||
symbol_table: symbol_table::SymbolTable,
|
||||
/// Contains information for type-checking
|
||||
type_context: typechecking::TypeContext<'static>,
|
||||
type_context: type_inference::TypeContext,
|
||||
/// Schala Parser
|
||||
active_parser: parsing::Parser,
|
||||
|
||||
@ -44,8 +44,7 @@ impl<'a> Schala<'a> {
|
||||
Schala {
|
||||
source_reference: SourceReference::new(),
|
||||
symbol_table: symbol_table::SymbolTable::new(),
|
||||
//state: eval::State::new(),
|
||||
type_context: typechecking::TypeContext::new(),
|
||||
type_context: type_inference::TypeContext::new(),
|
||||
active_parser: parsing::Parser::new(),
|
||||
eval_state: tree_walk_eval::State::new(),
|
||||
}
|
||||
@ -88,7 +87,7 @@ impl<'a> Schala<'a> {
|
||||
|
||||
// Typechecking
|
||||
// TODO typechecking not working
|
||||
let _overall_type = self.type_context.typecheck(&ast).map_err(SchalaError::from_type_error);
|
||||
//let _overall_type = self.type_context.typecheck(&ast).map_err(SchalaError::from_type_error);
|
||||
|
||||
let reduced_ir = reduced_ir::reduce(&ast, &self.symbol_table);
|
||||
|
||||
|
@ -8,7 +8,7 @@ use crate::ast::{
|
||||
Variant, VariantKind,
|
||||
};
|
||||
use crate::tokenizing::Location;
|
||||
use crate::typechecking::TypeId;
|
||||
use crate::type_inference::TypeId;
|
||||
|
||||
mod resolver;
|
||||
mod symbol_trie;
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
Alternative, Callable, Expression, FunctionDefinition, Literal, Lookup, Pattern, ReducedIR, Statement,
|
||||
},
|
||||
symbol_table::DefId,
|
||||
typechecking::TypeId,
|
||||
type_inference::TypeId,
|
||||
util::ScopeStack,
|
||||
};
|
||||
|
||||
|
73
schala-lang/language/src/type_inference/mod.rs
Normal file
73
schala-lang/language/src/type_inference/mod.rs
Normal file
@ -0,0 +1,73 @@
|
||||
use std::{fmt, rc::Rc};
|
||||
|
||||
//TODO need to hook this into the actual typechecking system somehow
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TypeId {
|
||||
local_name: Rc<String>,
|
||||
}
|
||||
|
||||
impl fmt::Display for TypeId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "TypeId:{}", self.local_name())
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeId {
|
||||
//TODO this is definitely incomplete
|
||||
pub fn lookup_name(name: &str) -> TypeId {
|
||||
TypeId { local_name: Rc::new(name.to_string()) }
|
||||
}
|
||||
|
||||
pub fn local_name(&self) -> &str {
|
||||
self.local_name.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TypeContext;
|
||||
|
||||
impl TypeContext {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TypeError {
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum TypeConst {
|
||||
Unit,
|
||||
Nat,
|
||||
Int,
|
||||
Float,
|
||||
StringT,
|
||||
Bool,
|
||||
Ordering,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Type {
|
||||
Const(TypeConst),
|
||||
//Var(TypeVar),
|
||||
Arrow { params: Vec<Type>, ret: Box<Type> },
|
||||
Compound { ty_name: String, args: Vec<Type> },
|
||||
}
|
||||
|
||||
macro_rules! ty {
|
||||
($type_name:ident) => {
|
||||
Type::Const(crate::type_inference::TypeConst::$type_name)
|
||||
};
|
||||
($t1:ident -> $t2:ident) => {
|
||||
Type::Arrow { params: vec![ty!($t1)], ret: box ty!($t2) }
|
||||
};
|
||||
($t1:ident -> $t2:ident -> $t3:ident) => {
|
||||
Type::Arrow { params: vec![ty!($t1), ty!($t2)], ret: box ty!($t3) }
|
||||
};
|
||||
($type_list:ident, $ret_type:ident) => {
|
||||
Type::Arrow { params: $type_list, ret: box $ret_type }
|
||||
};
|
||||
}
|
@ -1,8 +1,4 @@
|
||||
use std::{cmp::Eq, collections::HashMap, hash::Hash, ops::Deref};
|
||||
|
||||
pub fn deref_optional_box<T>(x: &Option<Box<T>>) -> Option<&T> {
|
||||
x.as_ref().map(Deref::deref)
|
||||
}
|
||||
use std::{cmp::Eq, collections::HashMap, hash::Hash};
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ScopeStack<'a, T: 'a, V: 'a, N = String>
|
||||
|
Loading…
Reference in New Issue
Block a user