Skip to content

Commit fb346be

Browse files
committed
Start of semantic analysis for polymorphic code
1 parent 79d7767 commit fb346be

File tree

6 files changed

+38
-5
lines changed

6 files changed

+38
-5
lines changed

tiger/src/env.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ impl<F: Clone + Frame> Env<F> {
127127
self.var_env.end_scope();
128128
}
129129

130+
pub fn begin_type_scope(&mut self) {
131+
self.type_env.begin_scope();
132+
}
133+
134+
pub fn end_type_scope(&mut self) {
135+
self.type_env.end_scope();
136+
}
137+
130138
pub fn enter_escape(&mut self, symbol: Symbol, escape: bool) {
131139
self.escape_env.enter(symbol, DepthEscape {
132140
depth: 0, // This value is not used anymore.

tiger/src/semant.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,8 +596,22 @@ impl<'a, F: Clone + Debug + Frame + PartialEq> SemanticAnalyzer<'a, F> {
596596
self.env.enter_type(name.node, Type::Var(TyVar::from_symbol(name.node)));
597597
}
598598

599-
for &WithPos { node: TypeDec { ref name, ref ty, .. }, .. } in type_declarations {
599+
for &WithPos { node: TypeDec { ref name, ref ty, ref ty_vars, .. }, .. } in type_declarations {
600+
let has_type_args = !ty_vars.idents.is_empty();
601+
if has_type_args {
602+
self.env.begin_type_scope();
603+
}
604+
let mut type_vars = vec![];
605+
for var in &ty_vars.idents {
606+
let type_var = self.new_type_var();
607+
type_vars.push(type_var);
608+
self.env.enter_type(var.node, Type::Var(type_var));
609+
}
610+
600611
let new_type = self.trans_ty(name.node, ty);
612+
if has_type_args {
613+
self.env.end_type_scope();
614+
}
601615
self.env.enter_type(name.node, new_type);
602616
}
603617
None
@@ -1407,6 +1421,7 @@ impl<'a, F: Clone + Debug + Frame + PartialEq> SemanticAnalyzer<'a, F> {
14071421
match ty.node.typ.node {
14081422
InnerType::Array { ref ident } => {
14091423
let ty = self.get_type(ident, AddError);
1424+
// FIXME: according to the book, the Unique should be at the outermost.
14101425
Type::App(TypeConstructor::new_unique(TypeConstructor::Array), vec![ty])
14111426
},
14121427
InnerType::Function { ref parameters, ref return_type } => {
@@ -1506,6 +1521,10 @@ impl<'a, F: Clone + Debug + Frame + PartialEq> SemanticAnalyzer<'a, F> {
15061521
(fields, data_layout, parent_methods)
15071522
}
15081523

1524+
fn new_type_var(&mut self) -> TyVar {
1525+
TyVar::from_symbol(self.symbols.unnamed())
1526+
}
1527+
15091528
fn duplicate_param(&mut self, param: &FieldWithPos) {
15101529
let ident = self.env.var_name(param.node.name);
15111530
self.add_error(Error::DuplicateParam {

tiger/src/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub struct ClassMethod {
5757
pub typ: FunctionType,
5858
}
5959

60-
#[derive(Clone, Debug, PartialEq)]
60+
#[derive(Clone, Copy, Debug, PartialEq)]
6161
pub struct TyVar(pub Symbol);
6262

6363
impl TyVar {

tiger/tests/polymorphism.stdout

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2
2+
4

tiger/tests/polymorphism.tig

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,16 @@ let type list<e> = {
3333
first = "test",
3434
second = "2"
3535
}
36-
/* FIXME: there's conflict between `var < 12` and `func<int>()`, so find a way to differentiate the syntax. */
3736
var my_two_some := twosome::<int> {
3837
first = 4,
3938
second = 2
4039
}
4140

4241
in
43-
f(string_pair); /* Should be an error. */
44-
f(my_two_some) /* Should be an error. */
42+
print(string_pair.second);
43+
print("\n");
44+
printi(two4s.head)
45+
/* TODO: correct code generation (monomorphisation) for polymorphic code. */
46+
/*f(string_pair); /* Should be an error. */ */
47+
/*f(my_two_some) /* Should be an error. */ */
4548
end

tiger/tests/test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ fn test_execution() {
4848
"loops",
4949
"merge",
5050
"nested",
51+
"polymorphism",
5152
"prettyprint",
5253
"pureTree",
5354
"queens",

0 commit comments

Comments
 (0)