Skip to content

Commit 9bb48ea

Browse files
committed
Switch to a type representation supporting parametric polymorphism
1 parent 0ada67f commit 9bb48ea

File tree

7 files changed

+567
-353
lines changed

7 files changed

+567
-353
lines changed

tiger/src/ast.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017-2019 Boucher, Antoni <bouanto@zoho.com>
2+
* Copyright (c) 2017-2024 Boucher, Antoni <bouanto@zoho.com>
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy of
55
* this software and associated documentation files (the "Software"), to deal in
@@ -147,6 +147,7 @@ pub struct FuncDeclaration {
147147
pub params: Vec<FieldWithPos>,
148148
pub pure: bool,
149149
pub result: Option<SymbolWithPos>,
150+
pub ty_vars: TypeVars,
150151
}
151152

152153
pub type FuncDeclarationWithPos = WithPos<FuncDeclaration>;
@@ -178,7 +179,24 @@ pub struct RecordField {
178179
pub type RecordFieldWithPos = WithPos<RecordField>;
179180

180181
#[derive(Clone, Debug, PartialEq)]
181-
pub enum Ty {
182+
pub struct Ty {
183+
pub typ: InnerTypeWithPos,
184+
pub args: TypeArgsWithPos,
185+
}
186+
187+
impl Ty {
188+
pub fn new(typ: InnerTypeWithPos) -> Self {
189+
Self {
190+
args: WithPos::new(TypeArgs {
191+
types: vec![],
192+
}, typ.pos),
193+
typ,
194+
}
195+
}
196+
}
197+
198+
#[derive(Clone, Debug, PartialEq)]
199+
pub enum InnerType {
182200
Array {
183201
ident: SymbolWithPos,
184202
},
@@ -195,12 +213,35 @@ pub enum Ty {
195213
Unit,
196214
}
197215

216+
pub type InnerTypeWithPos = WithPos<InnerType>;
217+
198218
#[derive(Clone, Debug, PartialEq)]
199219
pub struct TypeDec {
200220
pub name: SymbolWithPos,
201221
pub ty: TyWithPos,
222+
pub ty_vars: TypeVars,
202223
}
203224

225+
#[derive(Clone, Debug, PartialEq)]
226+
pub struct TypeVars {
227+
pub idents: Vec<SymbolWithPos>,
228+
}
229+
230+
impl TypeVars {
231+
pub fn new() -> Self {
232+
Self {
233+
idents: vec![],
234+
}
235+
}
236+
}
237+
238+
#[derive(Clone, Debug, PartialEq)]
239+
pub struct TypeArgs {
240+
pub types: Vec<TyWithPos>,
241+
}
242+
243+
pub type TypeArgsWithPos = WithPos<TypeArgs>;
244+
204245
pub type TypeDecWithPos = WithPos<TypeDec>;
205246

206247
pub type TyWithPos = WithPos<Ty>;

tiger/src/env.rs

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017-2019 Boucher, Antoni <bouanto@zoho.com>
2+
* Copyright (c) 2017-2024 Boucher, Antoni <bouanto@zoho.com>
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy of
55
* this software and associated documentation files (the "Software"), to deal in
@@ -26,10 +26,11 @@ use escape::{DepthEscape, EscapeEnv};
2626
use frame::Frame;
2727
use gen;
2828
use gen::{Access, Level};
29-
use position::WithPos;
3029
use symbol::{Strings, Symbol, Symbols};
3130
use temp::Label;
32-
use types::{Type, Unique};
31+
use types::Type;
32+
33+
use crate::types::{TyVar, TypeConstructor};
3334

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

7172
let object_symbol = type_env.symbol("Object");
7273
let answer_symbol = type_env.symbol("answer");
7374
let cont_symbol = type_env.symbol("cont");
7475
let string_consumer_symbol = type_env.symbol("stringConsumer");
7576

76-
let object_class = Type::Class {
77+
let object_class = Type::App(TypeConstructor::new_unique(TypeConstructor::Class {
7778
data_layout: String::new(),
7879
fields: vec![],
7980
methods: vec![],
8081
name: object_symbol,
8182
parent_class: None,
82-
unique: Unique::new(),
8383
vtable_name: Label::with_name("__vtable_Object"),
84-
};
84+
}), vec![]);
8585

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

9797
env.enter_type(object_symbol, object_class);
9898

99-
env.enter_type(answer_symbol, Type::Answer);
100-
env.enter_type(cont_symbol, Type::Function {
101-
parameters: vec![],
102-
return_type: Box::new(Type::Answer),
103-
});
104-
env.enter_type(string_consumer_symbol, Type::Function {
105-
parameters: vec![Type::String],
106-
return_type: Box::new(Type::Answer),
107-
});
99+
env.enter_type(answer_symbol, Type::new_answer());
100+
env.enter_type(cont_symbol, Type::App(TypeConstructor::Arrow, vec![Type::new_answer()]));
101+
env.enter_type(string_consumer_symbol, Type::App(TypeConstructor::Arrow, vec![Type::new_string(), Type::new_answer()]));
108102

109103
env
110104
}
@@ -180,27 +174,28 @@ impl<F: Clone + Frame> Env<F> {
180174

181175
pub fn external_functions(&mut self) -> BTreeMap<&'static str, (Vec<Type>, Type, bool)> {
182176
let mut functions = BTreeMap::new();
183-
functions.insert("print", (vec![Type::String], Type::Unit, false));
184-
functions.insert("printi", (vec![Type::Int], Type::Unit, false));
185-
functions.insert("flush", (vec![], Type::Unit, false));
186-
functions.insert("getchar", (vec![], Type::String, false));
187-
functions.insert("ord", (vec![Type::String], Type::Int, true));
188-
functions.insert("chr", (vec![Type::Int], Type::String, true));
189-
functions.insert("size", (vec![Type::String], Type::Int, true));
190-
functions.insert("substring", (vec![Type::String, Type::Int, Type::Int], Type::String, true));
191-
functions.insert("concat", (vec![Type::String, Type::String], Type::String, true));
192-
functions.insert("not", (vec![Type::Int], Type::Int, true));
193-
functions.insert("stringEqual", (vec![Type::String, Type::String], Type::Int, true));
194-
195-
let cont = Type::Name(WithPos::dummy(self.type_env.symbol("cont")), None);
196-
functions.insert("printP", (vec![Type::String, cont.clone()], Type::Answer, true));
197-
functions.insert("flushP", (vec![cont], Type::Answer, true));
198-
functions.insert("getcharP", (vec![Type::Name(WithPos::dummy(self.type_env.symbol("stringConsumer")), None)], Type::Answer, true));
199-
functions.insert("exit", (vec![], Type::Answer, true));
200-
201-
functions.insert("allocClass", (vec![Type::Int], Type::Int, true));
202-
functions.insert("allocRecord", (vec![Type::Int], Type::Int, true));
203-
functions.insert("initArray", (vec![Type::Int, Type::Int], Type::Int, true));
177+
functions.insert("print", (vec![Type::new_string()], Type::new_unit(), false));
178+
functions.insert("printi", (vec![Type::new_int()], Type::new_unit(), false));
179+
functions.insert("flush", (vec![], Type::new_unit(), false));
180+
functions.insert("getchar", (vec![], Type::new_string(), false));
181+
functions.insert("ord", (vec![Type::new_string()], Type::new_int(), true));
182+
functions.insert("chr", (vec![Type::new_int()], Type::new_string(), true));
183+
functions.insert("size", (vec![Type::new_string()], Type::new_int(), true));
184+
functions.insert("substring", (vec![Type::new_string(), Type::new_int(), Type::new_int()], Type::new_string(), true));
185+
functions.insert("concat", (vec![Type::new_string(), Type::new_string()], Type::new_string(), true));
186+
functions.insert("not", (vec![Type::new_int()], Type::new_int(), true));
187+
functions.insert("stringEqual", (vec![Type::new_string(), Type::new_string()], Type::new_int(), true));
188+
189+
let cont = Type::Var(TyVar::from_symbol(self.type_env.symbol("cont")));
190+
functions.insert("printP", (vec![Type::new_string(), cont.clone()], Type::new_answer(), true));
191+
functions.insert("flushP", (vec![cont], Type::new_answer(), true));
192+
let string_consumer = Type::Var(TyVar::from_symbol(self.type_env.symbol("stringConsumer")));
193+
functions.insert("getcharP", (vec![string_consumer], Type::new_answer(), true));
194+
functions.insert("exit", (vec![], Type::new_answer(), true));
195+
196+
functions.insert("allocClass", (vec![Type::new_int()], Type::new_int(), true));
197+
functions.insert("allocRecord", (vec![Type::new_int()], Type::new_int(), true));
198+
functions.insert("initArray", (vec![Type::new_int(), Type::new_int()], Type::new_int(), true));
204199
functions
205200
}
206201
}

tiger/src/lexer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ impl<R: Read> Lexer<R> {
189189
"new" => New,
190190
"nil" => Nil,
191191
"of" => Of,
192+
"poly" => Poly,
192193
"pure" => Pure,
193194
"then" => Then,
194195
"to" => To,

0 commit comments

Comments
 (0)