Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tiger/src/asm_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl<F: Frame> Gen<F> {
// Error cases:
Exp::Error | Exp::ExpSequence(_, _) | Exp::BinOp { left: box Exp::Error, .. }
| Exp::BinOp { right: box Exp::Error, .. } | Exp::BinOp { right: box Exp::Name(_), .. }
=> unreachable!(),
=> unreachable!("{:?}", expr),

Exp::BinOp { op: BinOp::Plus, left: box Exp::Name(label), right } => {
let instruction = Instruction::Move {
Expand Down
64 changes: 58 additions & 6 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 <bouanto@zoho.com>
* Copyright (c) 2017-2024 Boucher, Antoni <bouanto@zoho.com>
*
* 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 @@ -37,7 +37,7 @@ pub enum Declaration {
escape: bool, // TODO: is this field actually used?
init: ExprWithPos,
name: Symbol,
typ: Option<SymbolWithPos>,
typ: Option<TyWithPos>,
},
}

Expand All @@ -58,12 +58,13 @@ pub enum Expr {
Call {
args: Vec<ExprWithPos>,
function: Box<ExprWithPos>,
type_args: TypeArgsWithPos,
},
Closure {
body: Box<ExprWithPos>,
params: Vec<FieldWithPos>,
pure: bool,
result: Option<SymbolWithPos>,
result: Option<TyWithPos>,
},
ClosureParamField {
ident: SymbolWithPos,
Expand Down Expand Up @@ -113,6 +114,7 @@ pub enum Expr {
Record {
fields: Vec<RecordFieldWithPos>,
typ: SymbolWithPos,
type_args: TypeArgsWithPos,
},
Sequence(Vec<ExprWithPos>),
Str {
Expand All @@ -135,7 +137,7 @@ pub type ExprWithPos = WithPos<Expr>;
pub struct Field {
pub escape: bool,
pub name: Symbol,
pub typ: SymbolWithPos,
pub typ: TyWithPos,
}

pub type FieldWithPos = WithPos<Field>;
Expand All @@ -146,7 +148,8 @@ pub struct FuncDeclaration {
pub name: SymbolWithPos,
pub params: Vec<FieldWithPos>,
pub pure: bool,
pub result: Option<SymbolWithPos>,
pub result: Option<TyWithPos>,
pub ty_vars: TypeVars,
}

pub type FuncDeclarationWithPos = WithPos<FuncDeclaration>;
Expand Down Expand Up @@ -178,7 +181,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 +215,44 @@ pub enum Ty {
Unit,
}

pub type InnerTypeWithPos = WithPos<InnerType>;

#[derive(Clone, Debug, PartialEq)]
pub struct TypeDec {
pub name: SymbolWithPos,
pub ty: TyWithPos,
/// Generic types.
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>,
}

impl TypeArgs {
pub fn empty() -> Self {
Self {
types: vec![],
}
}
}

pub type TypeArgsWithPos = WithPos<TypeArgs>;

pub type TypeDecWithPos = WithPos<TypeDec>;

pub type TyWithPos = WithPos<Ty>;
Expand Down
79 changes: 41 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 <bouanto@zoho.com>
* Copyright (c) 2017-2024 Boucher, Antoni <bouanto@zoho.com>
*
* 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 @@ -133,6 +127,14 @@ impl<F: Clone + Frame> Env<F> {
self.var_env.end_scope();
}

pub fn begin_type_scope(&mut self) {
self.type_env.begin_scope();
}

pub fn end_type_scope(&mut self) {
self.type_env.end_scope();
}

pub fn enter_escape(&mut self, symbol: Symbol, escape: bool) {
self.escape_env.enter(symbol, DepthEscape {
depth: 0, // This value is not used anymore.
Expand Down Expand Up @@ -180,27 +182,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
}
}
3 changes: 2 additions & 1 deletion tiger/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl<R: Read> Lexer<R> {
}

fn colon_and_optional_equal(&mut self) -> Result<Token> {
self.two_char_token(vec![('=', ColonEqual)], Colon)
self.two_char_token(vec![('=', ColonEqual), (':', ColonColon)], Colon)
}

fn comment(&mut self) -> Result<()> {
Expand Down 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
Loading