parsing include lambda and Pass1 unifyVar
This commit is contained in:
parent
dad707924d
commit
26305b7e0d
5 changed files with 207 additions and 57 deletions
|
@ -2,3 +2,6 @@ name = "TComp"
|
||||||
uuid = "b858fc1c-1812-4b3c-a2e6-a1a64b2d44f1"
|
uuid = "b858fc1c-1812-4b3c-a2e6-a1a64b2d44f1"
|
||||||
authors = ["Tan Kian-ting <chenjt30@gmail.com>"]
|
authors = ["Tan Kian-ting <chenjt30@gmail.com>"]
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
Match = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf"
|
70
src/TComp.jl
70
src/TComp.jl
|
@ -1,7 +1,75 @@
|
||||||
module TComp
|
module TComp
|
||||||
include("./parser.jl")
|
include("./parser.jl")
|
||||||
using .Parser
|
using .Parser
|
||||||
|
using Match
|
||||||
|
|
||||||
|
|
||||||
|
inp = ARGS
|
||||||
|
f = open(ARGS[1], "r")
|
||||||
|
prog = read(f, String)
|
||||||
|
|
||||||
|
print(prog)
|
||||||
|
parsed = Parser.totalParse(prog)
|
||||||
|
print(parsed)
|
||||||
|
tmp_var_no = 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Pass 1 duplicated varname unified
|
||||||
|
function unifyVar(parsed, env)
|
||||||
|
@match parsed begin
|
||||||
|
# letrec is not considered
|
||||||
|
#[("%let", "id"), [ty, var], val, [("%lambda", "id"), args, body]] => nothing
|
||||||
|
|
||||||
|
[("%let", "id"), [ty, var], val, body] =>
|
||||||
|
begin
|
||||||
|
envNew = env
|
||||||
|
push!(envNew, var[1]) # push x of var = ("x", "id") in newEnv
|
||||||
|
res = [("%let", "id"),
|
||||||
|
[ty, unifyVar(var, envNew)],
|
||||||
|
unifyVar(val, env),
|
||||||
|
unifyVar(body, envNew)]
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
(var, "id") =>
|
||||||
|
begin
|
||||||
|
reversedEnv = reverse(env)
|
||||||
|
index = length(env) - findfirst(e -> e == var, reversedEnv) + 1
|
||||||
|
return (index, "id")
|
||||||
|
end
|
||||||
|
[(plus, "plus"), lhs, rhs] =>
|
||||||
|
begin
|
||||||
|
lhs_new = unifyVar(lhs, env)
|
||||||
|
rhs_new = unifyVar(rhs, env)
|
||||||
|
return [(plus, "plus"), lhs_new, rhs_new]
|
||||||
|
|
||||||
|
end
|
||||||
|
[(minus, "minus"), lhs, rhs] =>
|
||||||
|
begin
|
||||||
|
lhs_new = unifyVar(lhs, env)
|
||||||
|
rhs_new = unifyVar(rhs, env)
|
||||||
|
return [(minus, "minus"), lhs_new, rhs_new]
|
||||||
|
|
||||||
|
end
|
||||||
|
[("%call", "id"), callee, args...] =>
|
||||||
|
begin
|
||||||
|
unifiedCallee = unifyVar(callee, env)
|
||||||
|
unifiedArgs = map(x ->unifyVar(x, env), args[1])
|
||||||
|
|
||||||
|
return vcat([("%call", "id"), unifiedCallee], [unifiedArgs])
|
||||||
|
end
|
||||||
|
(c, "int") => return parsed
|
||||||
|
_ => "Error"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
emptyEnv = []
|
||||||
|
res = unifyVar(parsed, emptyEnv)
|
||||||
|
print(res)
|
||||||
|
|
||||||
|
|
||||||
|
close(f)
|
||||||
|
|
||||||
|
|
||||||
greet() = print("Hello World!")
|
|
||||||
|
|
||||||
end # module
|
end # module
|
||||||
|
|
181
src/parser.jl
181
src/parser.jl
|
@ -90,10 +90,11 @@ patternList = [("int", "\\d+"),
|
||||||
("lParen", "[\\(]"),
|
("lParen", "[\\(]"),
|
||||||
("rParen", "[\\)]"),
|
("rParen", "[\\)]"),
|
||||||
("plus", "[+]"),
|
("plus", "[+]"),
|
||||||
|
("funType", "[-][\\>]"),
|
||||||
("minus", "[\\-]"),
|
("minus", "[\\-]"),
|
||||||
("mul", "[\\*]"),
|
("mul", "[\\*]"),
|
||||||
("div", "[\\/]"),
|
("div", "[\\/]"),
|
||||||
("sp", "\\s+"),
|
("sp", "[\\n\\r ]+"),
|
||||||
("comma", "[,]"),
|
("comma", "[,]"),
|
||||||
("semicolon", "[;]"),
|
("semicolon", "[;]"),
|
||||||
("lambda", "[=][\\>]"),
|
("lambda", "[=][\\>]"),
|
||||||
|
@ -112,21 +113,15 @@ matchEachItem = Regex(tmp)
|
||||||
matchAll = "^(" * tmp * ")+\$"
|
matchAll = "^(" * tmp * ")+\$"
|
||||||
matchEntirely = Regex(matchAll)
|
matchEntirely = Regex(matchAll)
|
||||||
|
|
||||||
print(matchEntirely)
|
#println(matchEntirely)
|
||||||
|
|
||||||
|
"""
|
||||||
|
((int -> int) -> int)
|
||||||
|
add = (x , y) => x + y;
|
||||||
|
|
||||||
inp = """
|
|
||||||
((a, b, c)=>(d=>e)) add = add;
|
|
||||||
int a = 8;
|
int a = 8;
|
||||||
12 + foo(13*a,14,15) """
|
12 + foo(13*a,14,15)
|
||||||
|
"""
|
||||||
print("~~~\n")
|
|
||||||
isEntirelyMatched = match(matchEntirely, inp)
|
|
||||||
|
|
||||||
if isEntirelyMatched == false
|
|
||||||
print("illegal tokens contained.")
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function prettyString(ele)
|
function prettyString(ele)
|
||||||
|
@ -146,66 +141,112 @@ function prettyString(ele)
|
||||||
else #number
|
else #number
|
||||||
return string(ele)
|
return string(ele)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
mI = eachmatch(matchEachItem, inp)
|
function prettyStringLisp(ele)
|
||||||
|
if isa(ele, String)
|
||||||
|
return ele
|
||||||
|
elseif isa(ele, Tuple)
|
||||||
|
res = prettyStringLisp(ele[1])
|
||||||
|
return res
|
||||||
|
elseif isa(ele, Array)
|
||||||
|
mappedEle = map(prettyStringLisp, ele)
|
||||||
|
mappedString = "(" * join(mappedEle, " ") * ")"
|
||||||
|
return mappedString
|
||||||
|
elseif isa(ele, ParserResult)
|
||||||
|
res = prettyStringLisp(ele.matched)
|
||||||
|
return res
|
||||||
|
else #number
|
||||||
|
return string(ele)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function processKeys(x)
|
function processKeys(x)
|
||||||
keys_ = keys(x)
|
keys_ = keys(x)
|
||||||
return filter((i) -> x[i] != nothing, keys_)[1]
|
return filter((i) -> x[i] != nothing, keys_)[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
matchedList = map((x)->x.match, collect(mI))
|
|
||||||
|
|
||||||
groupNameList = map(processKeys, collect(mI))
|
|
||||||
|
|
||||||
zippedTokenList = collect(zip(matchedList, groupNameList))
|
|
||||||
|
|
||||||
print(zippedTokenList)
|
|
||||||
|
|
||||||
withoutSpaces = filter((x)-> x[2] != "sp", zippedTokenList)
|
|
||||||
initWrapped = ParserResult([], withoutSpaces)
|
|
||||||
|
|
||||||
|
|
||||||
test1 = initWrapped >> strng("123") >> (strng("+")|strng("-"))
|
|
||||||
test2 = initWrapped >> seq([strng("123"), strng("+")])
|
|
||||||
|
|
||||||
println(prettyString(test1))
|
#test1 = initWrapped >> strng("123") >> (strng("+")|strng("-"))
|
||||||
println(prettyString(test2))
|
#test2 = initWrapped >> seq([strng("123"), strng("+")])
|
||||||
|
|
||||||
|
#println(prettyString(test1))
|
||||||
|
#println(prettyString(test2))
|
||||||
|
|
||||||
"""
|
"""
|
||||||
atom = int | id
|
atom = int | id
|
||||||
unit = "(" unit ")" | atom
|
func = "(" fn_args ")" "=>" body
|
||||||
|
unit = func | "(" exp ")" | atom
|
||||||
args = unit ("," unit)*
|
args = unit ("," unit)*
|
||||||
factor = unit "(" args ")"
|
factor = unit "(" args ")"
|
||||||
term = (factor (*|/) factor) | factor
|
term = (factor (*|/) factor) | factor
|
||||||
exp = (term (+|-) term) | term
|
exp = (term (+|-) term) | term
|
||||||
|
|
||||||
tyOfArgs = ty ("," ty)*
|
|
||||||
tyOfFn = "(" ty => ty ")"
|
|
||||||
ty = id | tyOfFn | "(" tyOfArgs ")"
|
|
||||||
|
|
||||||
letexp = ty id "=" exp ";" body
|
letexp = ty id "=" exp ";" body
|
||||||
body = exp | letexp
|
body = exp | letexp
|
||||||
"""
|
"""
|
||||||
atom = typ("int") | typ("id")
|
atom = typ("int") | typ("id")
|
||||||
|
|
||||||
|
|
||||||
function longUnitAux(input)
|
|
||||||
rawFunc = seq([typ("lParen"), unit, typ("rParen")])
|
function fnArgItemAux(input)
|
||||||
|
rawFunc = seq([typ("comma"), typ("id")])
|
||||||
rawRes = rawFunc.fun(input)
|
rawRes = rawFunc.fun(input)
|
||||||
if rawRes != nothing
|
if rawRes != nothing
|
||||||
matched = rawRes.matched[2]
|
matched = rawRes.matched[2]
|
||||||
res = ParserResult(matched, rawRes.remained)
|
res = ParserResult(matched, rawRes.remained)
|
||||||
return res
|
return res
|
||||||
else
|
else
|
||||||
return rawRes
|
return nothing
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fnArgItem = Psr(fnArgItemAux)
|
||||||
|
|
||||||
|
function fnArgsAux(input)
|
||||||
|
rawFunc = seq([typ("id"), many0(fnArgItem)])
|
||||||
|
res = rawFunc.fun(input)
|
||||||
|
if res != nothing
|
||||||
|
matched = vcat([res.matched[1]], res.matched[2])
|
||||||
|
res = ParserResult(matched, res.remained)
|
||||||
|
return res
|
||||||
|
else
|
||||||
|
return nothing
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fnArgs = Psr(fnArgsAux)
|
||||||
|
|
||||||
|
function funcAux(input)
|
||||||
|
rawFunc = seq([typ("lParen"), fnArgs, typ("rParen"), typ("lambda"), body])
|
||||||
|
rawRes = rawFunc.fun(input)
|
||||||
|
if rawRes != nothing
|
||||||
|
matched = [("%lambda", "id"), rawRes.matched[2], rawRes.matched[5]]
|
||||||
|
res = ParserResult(matched, rawRes.remained)
|
||||||
|
return res
|
||||||
|
else
|
||||||
|
return nothing
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function longUnitAux(input)
|
||||||
|
rawFunc = seq([typ("lParen"), exp, typ("rParen")])
|
||||||
|
rawRes = rawFunc.fun(input)
|
||||||
|
if rawRes != nothing
|
||||||
|
matched = rawRes.matched[2]
|
||||||
|
res = ParserResult(matched, rawRes.remained)
|
||||||
|
return res
|
||||||
|
else
|
||||||
|
return nothing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function unitAux(input)
|
function unitAux(input)
|
||||||
|
fun = Psr(funcAux)
|
||||||
longUnit = Psr(longUnitAux)
|
longUnit = Psr(longUnitAux)
|
||||||
rawFunc = longUnit | atom
|
rawFunc = fun | longUnit | atom
|
||||||
res = rawFunc.fun(input)
|
res = rawFunc.fun(input)
|
||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
|
@ -220,7 +261,7 @@ function argItemAux(input)
|
||||||
res = ParserResult(matched, rawRes.remained)
|
res = ParserResult(matched, rawRes.remained)
|
||||||
return res
|
return res
|
||||||
else
|
else
|
||||||
return rawRes
|
return nothing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
argItem = Psr(argItemAux)
|
argItem = Psr(argItemAux)
|
||||||
|
@ -245,7 +286,7 @@ function longFactorAux(input)
|
||||||
res = ParserResult(matched, rawRes.remained)
|
res = ParserResult(matched, rawRes.remained)
|
||||||
return res
|
return res
|
||||||
else
|
else
|
||||||
return rawRes
|
return nothing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -266,7 +307,7 @@ function longTermAux(input)
|
||||||
res = ParserResult(matched, rawRes.remained)
|
res = ParserResult(matched, rawRes.remained)
|
||||||
return res
|
return res
|
||||||
else
|
else
|
||||||
return rawRes
|
return nothing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -288,7 +329,7 @@ function longExpAux(input)
|
||||||
res = ParserResult(matched, rawRes.remained)
|
res = ParserResult(matched, rawRes.remained)
|
||||||
return res
|
return res
|
||||||
else
|
else
|
||||||
return rawRes
|
return nothing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -302,48 +343,62 @@ exp = Psr(expAux)
|
||||||
|
|
||||||
|
|
||||||
"""tyOfArgs = "(" ty ("," ty)* ")"
|
"""tyOfArgs = "(" ty ("," ty)* ")"
|
||||||
tyOfFn = "(" ty => ty ")"
|
tyHead = tyOfArgs | tyOfFn | id
|
||||||
ty = id | tyOfFn | tyOfArgs """
|
tyOfFn = "(" tyHead -> ty ")"
|
||||||
|
ty = id | tyOfFn """
|
||||||
|
|
||||||
function tyArgItemAux(input)
|
function tyArgItemAux(input)
|
||||||
rawFunc = seq([typ("comma"), typ("id")])
|
rawFunc = seq([typ("comma"), ty])
|
||||||
rawRes = rawFunc.fun(input)
|
rawRes = rawFunc.fun(input)
|
||||||
if rawRes != nothing
|
if rawRes != nothing
|
||||||
matched = rawRes.matched[2]
|
matched = rawRes.matched[2]
|
||||||
res = ParserResult(matched, rawRes.remained)
|
res = ParserResult(matched, rawRes.remained)
|
||||||
return res
|
return res
|
||||||
else
|
else
|
||||||
return rawRes
|
return nothing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function tyOfArgsAux(input)
|
function tyOfArgsAux(input)
|
||||||
tyArgItem = Psr(tyArgItemAux)
|
tyArgItem = Psr(tyArgItemAux)
|
||||||
rawFunc = seq([typ("lParen"), typ("id"), many0(tyArgItem), typ("rParen")])
|
rawFunc = seq([typ("lParen"), ty, many0(tyArgItem), typ("rParen")])
|
||||||
res = rawFunc.fun(input)
|
res = rawFunc.fun(input)
|
||||||
if res != nothing
|
if res != nothing
|
||||||
matched = vcat([("%argType")], vcat([res.matched[2]], res.matched[3]))
|
matched = vcat([("%argType")], vcat([res.matched[2]], res.matched[3]))
|
||||||
res = ParserResult(matched, res.remained)
|
res = ParserResult(matched, res.remained)
|
||||||
|
return res
|
||||||
|
else
|
||||||
|
return nothing
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function tyHeadAux(input)
|
||||||
|
tyOfArgs = Psr(tyOfArgsAux)
|
||||||
|
tyOfFn = Psr(tyOfFnAux)
|
||||||
|
rawFunc = tyOfArgs | tyOfFn | typ("id")
|
||||||
|
res = rawFunc.fun(input)
|
||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
|
|
||||||
function tyOfFnAux(input)
|
function tyOfFnAux(input)
|
||||||
rawFunc = seq([typ("lParen"), ty, typ("lambda"), ty, typ("rParen")])
|
tyHead = Psr(tyHeadAux)
|
||||||
|
rawFunc = seq([typ("lParen"), tyHead, typ("funType"), ty, typ("rParen")])
|
||||||
rawRes = rawFunc.fun(input)
|
rawRes = rawFunc.fun(input)
|
||||||
if rawRes != nothing
|
if rawRes != nothing
|
||||||
matched = [("%funType", "id"), rawRes.matched[2], rawRes.matched[4]]
|
matched = [("%funType", "id"), rawRes.matched[2], rawRes.matched[4]]
|
||||||
res = ParserResult(matched, rawRes.remained)
|
res = ParserResult(matched, rawRes.remained)
|
||||||
return res
|
return res
|
||||||
else
|
else
|
||||||
return rawRes
|
return nothing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function tyAux(input)
|
function tyAux(input)
|
||||||
tyOfFn = Psr(tyOfArgsAux)
|
tyOfFn= Psr(tyOfFnAux)
|
||||||
tyOfArgs = Psr(tyOfFnAux)
|
rawFunc = tyOfFn | typ("id")
|
||||||
rawFunc = tyOfFn | tyOfArgs | typ("id")
|
|
||||||
res = rawFunc.fun(input)
|
res = rawFunc.fun(input)
|
||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
|
@ -363,7 +418,7 @@ function letExpAux(input)
|
||||||
res = ParserResult(matched, rawRes.remained)
|
res = ParserResult(matched, rawRes.remained)
|
||||||
return res
|
return res
|
||||||
else
|
else
|
||||||
return rawRes
|
return nothing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -371,8 +426,24 @@ letExp = Psr(letExpAux)
|
||||||
|
|
||||||
body = letExp | exp
|
body = letExp | exp
|
||||||
|
|
||||||
test3 = initWrapped >> body
|
function totalParse(prog)
|
||||||
println(prettyString(test3))
|
isEntirelyMatched = match(matchEntirely, prog)
|
||||||
|
if isEntirelyMatched == false
|
||||||
|
throw("illegal tokens contained.")
|
||||||
|
end
|
||||||
|
|
||||||
|
mI = eachmatch(matchEachItem, prog)
|
||||||
|
matchedList = map((x)->x.match, collect(mI))
|
||||||
|
groupNameList = map(processKeys, collect(mI))
|
||||||
|
zippedTokenList = collect(zip(matchedList, groupNameList))
|
||||||
|
print(zippedTokenList)
|
||||||
|
|
||||||
|
withoutSpaces = filter((x)-> x[2] != "sp", zippedTokenList)
|
||||||
|
initWrapped = ParserResult([], withoutSpaces)
|
||||||
|
res = initWrapped >> body
|
||||||
|
println(prettyStringLisp(res))
|
||||||
|
return res.matched
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
3
test/prog.tc
Normal file
3
test/prog.tc
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
(int -> int)
|
||||||
|
addmulti2 = (x , y) => (x + y) * 2;
|
||||||
|
addmulti2(40,10)
|
5
test/prog1.tc
Normal file
5
test/prog1.tc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
int a = 12;
|
||||||
|
int b = 12;
|
||||||
|
int a = 15;
|
||||||
|
int d = 20;
|
||||||
|
a + d((0 - a), b)
|
Loading…
Reference in a new issue