move compiler study to base so names are smaller

This commit is contained in:
Rígille S. B. Menezes 2021-08-06 21:38:21 -03:00
parent 842f1c478e
commit 5c968ac99f
4 changed files with 179 additions and 179 deletions

92
base/Tiger.kind Normal file
View File

@ -0,0 +1,92 @@
// i'm studying compilers using "modern compiler implementation in ML" by Andrew Appel
// translating to Kind as I go. i'm not too worried about following the book too closely.
// for example i'll likely use kind's `Parser` to parse programs instead of Lex and Yacc.
// but i'm using ML's naming conventions. it looks ugly but makes lookups easier.
// position on source code, to produce error messages
Tiger.pos: Type
Pair<Nat, Nat>
Tiger.symbol: Type
String
type Tiger.var {
SimpleVar(name: Tiger.symbol, pos: Tiger.pos)
FieldVar(var: Tiger.var, name: Tiger.symbol, pos: Tiger.pos)
SubscriptVar(var: Tiger.var, exp: Tiger.exp, pos: Tiger.pos)
}
type Tiger.record_fields {
new(
name: Tiger.symbol
args: List<Tiger.exp>
pos: Tiger.pos
)
}
type Tiger.exp {
NilExp
VarExp(var: Tiger.var)
IntExp(val: Int)
StringExp(val: String, pos: Tiger.pos)
CallExp(
func: Tiger.symbol
args: List<Tiger.exp>
pos: Tiger.pos
)
OpExp(
left: Tiger.exp
oper: Tiger.oper
right: Tiger.exp
pos: Tiger.pos
)
RecordExp(
fields: List<Tiger.record_fields>
typ: Tiger.symbol
pos: Tiger.pos
)
SeqExp(
val: List<Tiger.exp>
)
AssignExp(
var: Tiger.var
exp: Tiger.exp
pos: Tiger.pos
)
IfExp(
test: Tiger.exp
then: Tiger.exp
else: Maybe<Tiger.exp>
)
WhileExp(
test: Tiger.exp
body: Tiger.exp
pos: Tiger.pos
)
ForExp(
var: Tiger.symbol
escape: Bool
lo: Tiger.exp
hi: Tiger.exp
body: Tiger.exp
pos: Tiger.pos
)
BreakExp(
pos: Tiger.pos
)
LetExp(
decs: List<Tiger.dec>
body: Tiger.exp
pos: Tiger.pos
)
ArrayExp(
typ: Tiger.symbol
size: Tiger.exp
pos: Tiger.pos
)
}
type Tiger.oper {
}
type Tiger.dec {
}

87
base/Tiger/SL.kind Normal file
View File

@ -0,0 +1,87 @@
// straight-line programs Type and (very inefficient) interpreter
// statement
type Tiger.SL.Stm {
CompoundStm(fst: Tiger.SL.Stm, snd: Tiger.SL.Stm)
AssignStm(id: String, exp: Tiger.SL.Exp)
PrintStm(exp_list: List<Tiger.SL.Exp>)
}
// expression
type Tiger.SL.Exp {
IdExp(id: String)
NumExp(num: Int) // #TODO include other numbers?
OpExp(op: Tiger.SL.Binop, fst: Tiger.SL.Exp, snd: Tiger.SL.Exp)
EseqExp(stm: Tiger.SL.Stm, exp: Tiger.SL.Exp)
}
type Tiger.SL.ExpList {
PairExpList(head: Tiger.SL.Exp, tail: Tiger.SL.ExpList)
LastExpList(head: Tiger.SL.Exp)
}
type Tiger.SL.Binop {
plus
minus
times
div
}
maxargs(stm: Tiger.SL.Stm): Nat
case stm {
CompoundStm: Nat.max(maxargs(stm.fst), maxargs(stm.snd))
AssignStm: 0
PrintStm: List.length!(stm.exp_list)
}
Tiger.SL.interpStm(stm: Tiger.SL.Stm, table: List<Pair<String, Int>>): List<Pair<String, Int>>
case stm {
CompoundStm:
let new_table = Tiger.SL.interpStm(stm.fst, table)
Tiger.SL.interpStm(stm.snd, new_table)
AssignStm:
let {i, new_table} = Tiger.SL.interpExp(stm.exp, table)
{stm.id, i} & new_table
PrintStm:
for exp in stm.exp_list with table:
let {i, table} = Tiger.SL.interpExp(exp, table)
log(Int.show(i))
table
table
}
Tiger.SL.lookup(id: String, table: List<Pair<String, Int>>): Int
case table {
nil:
0 :: Int
cons:
let {table_id, val} = table.head
if id =? table_id then
val
else
Tiger.SL.lookup(id, table.tail)
}
Tiger.SL.interpExp(exp: Tiger.SL.Exp, table: List<Pair<String, Int>>): Pair<Int, List<Pair<String, Int>>>
case exp {
IdExp:
{Tiger.SL.lookup(exp.id, table), table}
NumExp:
{exp.num, table}
OpExp:
let {fst_val, table} = Tiger.SL.interpExp(exp.fst, table)
let {snd_val, table} = Tiger.SL.interpExp(exp.snd, table)
case exp.op {
plus:
{fst_val + snd_val, table}
minus:
{fst_val - snd_val, table}
times:
{fst_val * snd_val, table}
div:
{fst_val / snd_val, table}
}
EseqExp:
let table = Tiger.SL.interpStm(exp.stm, table)
Tiger.SL.interpExp(exp.exp, table)
}

View File

@ -1,92 +0,0 @@
// i'm studying compilers using "modern compiler implementation in ML" by Andrew Appel
// translating to Kind as I go. i'm not too worried about following the book too closely.
// for example i'll likely use kind's `Parser` to parse programs instead of Lex and Yacc.
// but i'm using ML's naming conventions. it looks ugly but makes lookups easier.
// position on source code, to produce error messages
User.rigille.Tiger.pos: Type
Pair<Nat, Nat>
User.rigille.Tiger.symbol: Type
String
type User.rigille.Tiger.var {
SimpleVar(name: User.rigille.Tiger.symbol, pos: User.rigille.Tiger.pos)
FieldVar(var: User.rigille.Tiger.var, name: User.rigille.Tiger.symbol, pos: User.rigille.Tiger.pos)
SubscriptVar(var: User.rigille.Tiger.var, exp: User.rigille.Tiger.exp, pos: User.rigille.Tiger.pos)
}
type User.rigille.Tiger.record_fields {
new(
name: User.rigille.Tiger.symbol
args: List<User.rigille.Tiger.exp>
pos: User.rigille.Tiger.pos
)
}
type User.rigille.Tiger.exp {
NilExp
VarExp(var: User.rigille.Tiger.var)
IntExp(val: Int)
StringExp(val: String, pos: User.rigille.Tiger.pos)
CallExp(
func: User.rigille.Tiger.symbol
args: List<User.rigille.Tiger.exp>
pos: User.rigille.Tiger.pos
)
OpExp(
left: User.rigille.Tiger.exp
oper: User.rigille.Tiger.oper
right: User.rigille.Tiger.exp
pos: User.rigille.Tiger.pos
)
RecordExp(
fields: List<User.rigille.Tiger.record_fields>
typ: User.rigille.Tiger.symbol
pos: User.rigille.Tiger.pos
)
SeqExp(
val: List<User.rigille.Tiger.exp>
)
AssignExp(
var: User.rigille.Tiger.var
exp: User.rigille.Tiger.exp
pos: User.rigille.Tiger.pos
)
IfExp(
test: User.rigille.Tiger.exp
then: User.rigille.Tiger.exp
else: Maybe<User.rigille.Tiger.exp>
)
WhileExp(
test: User.rigille.Tiger.exp
body: User.rigille.Tiger.exp
pos: User.rigille.Tiger.pos
)
ForExp(
var: User.rigille.Tiger.symbol
escape: Bool
lo: User.rigille.Tiger.exp
hi: User.rigille.Tiger.exp
body: User.rigille.Tiger.exp
pos: User.rigille.Tiger.pos
)
BreakExp(
pos: User.rigille.Tiger.pos
)
LetExp(
decs: List<User.rigille.Tiger.dec>
body: User.rigille.Tiger.exp
pos: User.rigille.Tiger.pos
)
ArrayExp(
typ: User.rigille.Tiger.symbol
size: User.rigille.Tiger.exp
pos: User.rigille.Tiger.pos
)
}
type User.rigille.Tiger.oper {
}
type User.rigille.Tiger.dec {
}

View File

@ -1,87 +0,0 @@
// straight-line programs Type and (very inefficient) interpreter
// statement
type User.rigille.Tiger.SL.Stm {
CompoundStm(fst: User.rigille.Tiger.SL.Stm, snd: User.rigille.Tiger.SL.Stm)
AssignStm(id: String, exp: User.rigille.Tiger.SL.Exp)
PrintStm(exp_list: List<User.rigille.Tiger.SL.Exp>)
}
// expression
type User.rigille.Tiger.SL.Exp {
IdExp(id: String)
NumExp(num: Int) // #TODO include other numbers?
OpExp(op: User.rigille.Tiger.SL.Binop, fst: User.rigille.Tiger.SL.Exp, snd: User.rigille.Tiger.SL.Exp)
EseqExp(stm: User.rigille.Tiger.SL.Stm, exp: User.rigille.Tiger.SL.Exp)
}
type User.rigille.Tiger.SL.ExpList {
PairExpList(head: User.rigille.Tiger.SL.Exp, tail: User.rigille.Tiger.SL.ExpList)
LastExpList(head: User.rigille.Tiger.SL.Exp)
}
type User.rigille.Tiger.SL.Binop {
plus
minus
times
div
}
maxargs(stm: User.rigille.Tiger.SL.Stm): Nat
case stm {
CompoundStm: Nat.max(maxargs(stm.fst), maxargs(stm.snd))
AssignStm: 0
PrintStm: List.length!(stm.exp_list)
}
User.rigille.Tiger.SL.interpStm(stm: User.rigille.Tiger.SL.Stm, table: List<Pair<String, Int>>): List<Pair<String, Int>>
case stm {
CompoundStm:
let new_table = User.rigille.Tiger.SL.interpStm(stm.fst, table)
User.rigille.Tiger.SL.interpStm(stm.snd, new_table)
AssignStm:
let {i, new_table} = User.rigille.Tiger.SL.interpExp(stm.exp, table)
{stm.id, i} & new_table
PrintStm:
for exp in stm.exp_list with table:
let {i, table} = User.rigille.Tiger.SL.interpExp(exp, table)
log(Int.show(i))
table
table
}
User.rigille.Tiger.SL.lookup(id: String, table: List<Pair<String, Int>>): Int
case table {
nil:
0 :: Int
cons:
let {table_id, val} = table.head
if id =? table_id then
val
else
User.rigille.Tiger.SL.lookup(id, table.tail)
}
User.rigille.Tiger.SL.interpExp(exp: User.rigille.Tiger.SL.Exp, table: List<Pair<String, Int>>): Pair<Int, List<Pair<String, Int>>>
case exp {
IdExp:
{User.rigille.Tiger.SL.lookup(exp.id, table), table}
NumExp:
{exp.num, table}
OpExp:
let {fst_val, table} = User.rigille.Tiger.SL.interpExp(exp.fst, table)
let {snd_val, table} = User.rigille.Tiger.SL.interpExp(exp.snd, table)
case exp.op {
plus:
{fst_val + snd_val, table}
minus:
{fst_val - snd_val, table}
times:
{fst_val * snd_val, table}
div:
{fst_val / snd_val, table}
}
EseqExp:
let table = User.rigille.Tiger.SL.interpStm(exp.stm, table)
User.rigille.Tiger.SL.interpExp(exp.exp, table)
}