Skip to content

Commit

Permalink
Switch to a type representation supporting parametric polymorphism
Browse files Browse the repository at this point in the history
  • Loading branch information
antoyo committed Nov 12, 2024
1 parent 0ada67f commit c150d79
Show file tree
Hide file tree
Showing 7 changed files with 559 additions and 352 deletions.
45 changes: 43 additions & 2 deletions tiger/src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019 Boucher, Antoni <[email protected]>
* Copyright (c) 2017-2024 Boucher, Antoni <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
Expand Down Expand Up @@ -147,6 +147,7 @@ pub struct FuncDeclaration {
pub params: Vec<FieldWithPos>,
pub pure: bool,
pub result: Option<SymbolWithPos>,
pub ty_vars: TypeVars,
}

pub type FuncDeclarationWithPos = WithPos<FuncDeclaration>;
Expand Down Expand Up @@ -178,7 +179,24 @@ pub struct RecordField {
pub type RecordFieldWithPos = WithPos<RecordField>;

#[derive(Clone, Debug, PartialEq)]
pub enum Ty {
pub struct Ty {
pub typ: InnerTypeWithPos,
pub args: TypeArgsWithPos,
}

impl Ty {
pub fn new(typ: InnerTypeWithPos) -> Self {
Self {
args: WithPos::new(TypeArgs {
types: vec![],
}, typ.pos),
typ,
}
}
}

#[derive(Clone, Debug, PartialEq)]
pub enum InnerType {
Array {
ident: SymbolWithPos,
},
Expand All @@ -195,12 +213,35 @@ pub enum Ty {
Unit,
}

pub type InnerTypeWithPos = WithPos<InnerType>;

#[derive(Clone, Debug, PartialEq)]
pub struct TypeDec {
pub name: SymbolWithPos,
pub ty: TyWithPos,
pub ty_vars: TypeVars,
}

#[derive(Clone, Debug, PartialEq)]
pub struct TypeVars {
pub idents: Vec<SymbolWithPos>,
}

impl TypeVars {
pub fn new() -> Self {
Self {
idents: vec![],
}
}
}

#[derive(Clone, Debug, PartialEq)]
pub struct TypeArgs {
pub types: Vec<TyWithPos>,
}

pub type TypeArgsWithPos = WithPos<TypeArgs>;

pub type TypeDecWithPos = WithPos<TypeDec>;

pub type TyWithPos = WithPos<Ty>;
Expand Down
71 changes: 33 additions & 38 deletions tiger/src/env.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019 Boucher, Antoni <[email protected]>
* Copyright (c) 2017-2024 Boucher, Antoni <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
Expand All @@ -26,10 +26,11 @@ use escape::{DepthEscape, EscapeEnv};
use frame::Frame;
use gen;
use gen::{Access, Level};
use position::WithPos;
use symbol::{Strings, Symbol, Symbols};
use temp::Label;
use types::{Type, Unique};
use types::Type;

use crate::types::{TyVar, TypeConstructor};

#[derive(Clone, Debug)]
pub enum Entry<F: Clone + Frame> {
Expand Down Expand Up @@ -64,24 +65,23 @@ impl<F: Clone + Frame> Env<F> {
pub fn new(strings: &Rc<Strings>, escape_env: EscapeEnv) -> Self {
let mut type_env = Symbols::new(Rc::clone(strings));
let int_symbol = type_env.symbol("int");
type_env.enter(int_symbol, Type::Int);
type_env.enter(int_symbol, Type::new_int());
let string_symbol = type_env.symbol("string");
type_env.enter(string_symbol, Type::String);
type_env.enter(string_symbol, Type::new_string());

let object_symbol = type_env.symbol("Object");
let answer_symbol = type_env.symbol("answer");
let cont_symbol = type_env.symbol("cont");
let string_consumer_symbol = type_env.symbol("stringConsumer");

let object_class = Type::Class {
let object_class = Type::App(TypeConstructor::new_unique(TypeConstructor::Class {
data_layout: String::new(),
fields: vec![],
methods: vec![],
name: object_symbol,
parent_class: None,
unique: Unique::new(),
vtable_name: Label::with_name("__vtable_Object"),
};
}), vec![]);

let var_env = Symbols::new(Rc::clone(strings));
let mut env = Self {
Expand All @@ -96,15 +96,9 @@ impl<F: Clone + Frame> Env<F> {

env.enter_type(object_symbol, object_class);

env.enter_type(answer_symbol, Type::Answer);
env.enter_type(cont_symbol, Type::Function {
parameters: vec![],
return_type: Box::new(Type::Answer),
});
env.enter_type(string_consumer_symbol, Type::Function {
parameters: vec![Type::String],
return_type: Box::new(Type::Answer),
});
env.enter_type(answer_symbol, Type::new_answer());
env.enter_type(cont_symbol, Type::App(TypeConstructor::Arrow, vec![Type::new_answer()]));
env.enter_type(string_consumer_symbol, Type::App(TypeConstructor::Arrow, vec![Type::new_string(), Type::new_answer()]));

env
}
Expand Down Expand Up @@ -180,27 +174,28 @@ impl<F: Clone + Frame> Env<F> {

pub fn external_functions(&mut self) -> BTreeMap<&'static str, (Vec<Type>, Type, bool)> {
let mut functions = BTreeMap::new();
functions.insert("print", (vec![Type::String], Type::Unit, false));
functions.insert("printi", (vec![Type::Int], Type::Unit, false));
functions.insert("flush", (vec![], Type::Unit, false));
functions.insert("getchar", (vec![], Type::String, false));
functions.insert("ord", (vec![Type::String], Type::Int, true));
functions.insert("chr", (vec![Type::Int], Type::String, true));
functions.insert("size", (vec![Type::String], Type::Int, true));
functions.insert("substring", (vec![Type::String, Type::Int, Type::Int], Type::String, true));
functions.insert("concat", (vec![Type::String, Type::String], Type::String, true));
functions.insert("not", (vec![Type::Int], Type::Int, true));
functions.insert("stringEqual", (vec![Type::String, Type::String], Type::Int, true));

let cont = Type::Name(WithPos::dummy(self.type_env.symbol("cont")), None);
functions.insert("printP", (vec![Type::String, cont.clone()], Type::Answer, true));
functions.insert("flushP", (vec![cont], Type::Answer, true));
functions.insert("getcharP", (vec![Type::Name(WithPos::dummy(self.type_env.symbol("stringConsumer")), None)], Type::Answer, true));
functions.insert("exit", (vec![], Type::Answer, true));

functions.insert("allocClass", (vec![Type::Int], Type::Int, true));
functions.insert("allocRecord", (vec![Type::Int], Type::Int, true));
functions.insert("initArray", (vec![Type::Int, Type::Int], Type::Int, true));
functions.insert("print", (vec![Type::new_string()], Type::new_unit(), false));
functions.insert("printi", (vec![Type::new_int()], Type::new_unit(), false));
functions.insert("flush", (vec![], Type::new_unit(), false));
functions.insert("getchar", (vec![], Type::new_string(), false));
functions.insert("ord", (vec![Type::new_string()], Type::new_int(), true));
functions.insert("chr", (vec![Type::new_int()], Type::new_string(), true));
functions.insert("size", (vec![Type::new_string()], Type::new_int(), true));
functions.insert("substring", (vec![Type::new_string(), Type::new_int(), Type::new_int()], Type::new_string(), true));
functions.insert("concat", (vec![Type::new_string(), Type::new_string()], Type::new_string(), true));
functions.insert("not", (vec![Type::new_int()], Type::new_int(), true));
functions.insert("stringEqual", (vec![Type::new_string(), Type::new_string()], Type::new_int(), true));

let cont = Type::Var(TyVar::from_symbol(self.type_env.symbol("cont")));
functions.insert("printP", (vec![Type::new_string(), cont.clone()], Type::new_answer(), true));
functions.insert("flushP", (vec![cont], Type::new_answer(), true));
let string_consumer = Type::Var(TyVar::from_symbol(self.type_env.symbol("stringConsumer")));
functions.insert("getcharP", (vec![string_consumer], Type::new_answer(), true));
functions.insert("exit", (vec![], Type::new_answer(), true));

functions.insert("allocClass", (vec![Type::new_int()], Type::new_int(), true));
functions.insert("allocRecord", (vec![Type::new_int()], Type::new_int(), true));
functions.insert("initArray", (vec![Type::new_int(), Type::new_int()], Type::new_int(), true));
functions
}
}
1 change: 1 addition & 0 deletions tiger/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ impl<R: Read> Lexer<R> {
"new" => New,
"nil" => Nil,
"of" => Of,
"poly" => Poly,
"pure" => Pure,
"then" => Then,
"to" => To,
Expand Down
Loading

0 comments on commit c150d79

Please sign in to comment.