Add typeck Type type

This commit is contained in:
Alex Bethel 2022-08-12 21:33:35 -06:00
parent cd0353b31a
commit 01a6a5bbba
3 changed files with 44 additions and 8 deletions

View file

@ -2,13 +2,13 @@
use std::{error::Error, fmt::Display, fs::File, io::Write, process::exit, str::FromStr}; use std::{error::Error, fmt::Display, fs::File, io::Write, process::exit, str::FromStr};
use clap::Parser;
use drimc_rs::{ use drimc_rs::{
ast2ir::ast2ir, ast2ir::ast2ir,
backends, backends,
parser::{parser, ParserError, ParserMeta}, parser::{parser, ParserError, ParserMeta},
typeck::typeck, typeck::typeck,
}; };
use clap::Parser;
/// Optimization levels. /// Optimization levels.
#[derive(Debug)] #[derive(Debug)]
@ -256,7 +256,7 @@ fn main() {
let source = std::fs::read_to_string(&args.source_file)?; let source = std::fs::read_to_string(&args.source_file)?;
let meta = ParserMeta::default(); let meta = ParserMeta::default();
let ast = chumsky::Parser::parse(&parser(&meta), source).map_err(ParserError)?; let ast = chumsky::Parser::parse(&parser(&meta), source).map_err(ParserError)?;
typeck(&ast)?; let ast = typeck(ast)?;
let ir = ast2ir(ast); let ir = ast2ir(ast);

View file

@ -2,6 +2,8 @@
use num_bigint::BigUint; use num_bigint::BigUint;
use crate::typeck;
/// A concrete syntax tree. This represents the full content of a Drim program, including all /// A concrete syntax tree. This represents the full content of a Drim program, including all
/// whitespace, comments, and tokens: the source code of the original program can be recovered /// whitespace, comments, and tokens: the source code of the original program can be recovered
/// completely using the syntax tree. /// completely using the syntax tree.
@ -68,7 +70,7 @@ pub enum ClassMember {
/// The type of the overall function; this is filled in by the typechecker, and is left /// The type of the overall function; this is filled in by the typechecker, and is left
/// blank by the parser. /// blank by the parser.
typ: Option<Type>, typ: Option<typeck::Type>,
}, },
/// Declaration of a type that is a literal alias for another type. /// Declaration of a type that is a literal alias for another type.
@ -98,7 +100,7 @@ pub struct Expr {
pub kind: ExprKind, pub kind: ExprKind,
/// An optional type signature, left as `None` by the parser and added by the type checker. /// An optional type signature, left as `None` by the parser and added by the type checker.
pub typ: Option<Type>, pub typ: Option<typeck::Type>,
} }
/// The different kinds of expressions. /// The different kinds of expressions.
@ -266,7 +268,7 @@ pub enum Pattern {
} }
/// Namespaced identifiers. /// Namespaced identifiers.
#[derive(Clone, Debug)] #[derive(Clone, Debug, Hash, PartialEq)]
pub struct Identifier { pub struct Identifier {
/// The elements of the identifier; there must be at least one of these. /// The elements of the identifier; there must be at least one of these.
pub elems: Vec<String>, pub elems: Vec<String>,

View file

@ -1,8 +1,10 @@
//! Type checker. //! Type checker.
use std::{error::Error, fmt::Display}; use std::{collections::BTreeMap, error::Error, fmt::Display};
use crate::syntax::SyntaxTree; use num_bigint::BigInt;
use crate::syntax::{Identifier, SyntaxTree};
/// A compile-time type error from the user's source code. /// A compile-time type error from the user's source code.
#[derive(Debug)] #[derive(Debug)]
@ -16,7 +18,39 @@ impl Display for TypeError {
impl Error for TypeError {} impl Error for TypeError {}
/// A type known at compile time. While this resembles the AST `Type` structure, this enum is
/// optimized for unifying types against one another and representing compiler-generated types
/// rather than strictly representing named types.
#[derive(Debug, Clone, PartialEq)]
pub enum Type {
/// `Foo`
Named(Identifier),
/// `List Int`
Application {
/// The function being applied. This must be a generic type.
function: Box<Type>,
/// The type given as an argument to the type.
expression: Box<Type>,
},
/// `(a, b)`
Tuple(Vec<Type>),
/// `{ a: x, b: y }`
Record(BTreeMap<String, Type>),
/// Compiler-internal type representing an arbitrary-precision integer whose value is known at
/// compile time. This is the default type of integer literals. A `CompInt` can be converted to
/// an actual integer type via implicit application of the `fromCompInt` generic function.
CompInt(BigInt),
/// Compiler-internal type representing a string literal. See `CompInt`.
CompString(String),
}
/// Type-checks the syntax tree. /// Type-checks the syntax tree.
pub fn typeck(_: &SyntaxTree) -> Result<(), TypeError> { pub fn typeck(_: SyntaxTree) -> Result<SyntaxTree, TypeError> {
todo!() todo!()
} }