Browse Source

desugaring for let/def expressions, more error handling, expanded test cases

pull/1/head
Wesley Kerfoot 11 years ago
parent
commit
7589d5c4d2
  1. 11
      desugar.js
  2. 40
      parse.js
  3. 5
      pprint.js
  4. 3
      representation.js
  5. 26
      test.jl

11
desugar.js

@ -20,11 +20,16 @@ function desugarList(lst) {
}
function desugarDefFunc(def) {
return new typ.Def(def.ident, new typ.FuncT(desugar(def.params), desugar(def.body)));
return new typ.Def(def.ident,
new typ.FuncT(desugar(def.params),
desugar(def.body)));
}
//function desugarString(str) {
function desugarLet(stx) {
var values = stx.pairs.map(desugar);
return new typ.LetExp(values, desugar(stx.body));
}
function desugar(stx) {
switch (stx.exprType) {
@ -59,6 +64,8 @@ function desugar(stx) {
return stx;
case "Integer":
return stx;
case "Let":
return desugarLet(stx);
default:
return stx;
}

40
parse.js

@ -188,8 +188,8 @@ function parseLetForm(tokens, linenum, charnum) {
charnum,
"Unexpected end of source");
}
linenum = fst(tokens)[2];
charnum = fst(tokens)[3];
linenum = fst(tokens)[3];
charnum = fst(tokens)[2];
tokens.pop();
if (tokens.length <= 0) {
throw error.JSyntaxError(linenum,
@ -197,6 +197,12 @@ function parseLetForm(tokens, linenum, charnum) {
"let/def form must have a body");
}
var body = parse(tokens);
if (body.exprType === "Definition" ||
body.exprType === "FunctionDefinition") {
throw error.JSyntaxError(linenum,
charnum,
"Body of a let/def expression cannot be a definition");
}
return new typ.LetExp(pairs, body);
}
@ -250,14 +256,21 @@ function parseLetBinding(tokens, linenum, charnum) {
}
tokens.pop();
if (!notFollowedBy(tokens,
["def", "comma", "arrow", "right_brace", "right_square"],
["comma", "arrow", "right_brace", "right_square"],
linenum,
charnum)) {
throw error.JSyntaxError(linenum,
charnum,
"The binding of " + identifier.val + " must not be followed by " + fst(tokens)[0]);
}
return new typ.Def(name, parse(tokens));
var bound = parse(tokens);
if (bound.exprType === "Definition" ||
bound.exprType === "FunctionDefinition") {
throw error.JSyntaxError(linenum,
charnum,
"A definition cannot be the value of a binding");
}
return new typ.Def(name, bound);
}
function parseLetItem(tokens) {
@ -289,8 +302,8 @@ function parseDef(tokens, linenum, charnum) {
/* It's a let/def form */
tokens.pop();
return parseLetForm(tokens,
fst(tokens)[2],
fst(tokens)[3]);
fst(tokens)[3],
fst(tokens)[2]);
}
if (notFollowedBy(tokens, ["identifier"], linenum, charnum)) {
@ -307,14 +320,21 @@ function parseDef(tokens, linenum, charnum) {
linenum = fst(tokens)[3];
charnum = fst(tokens)[2];
if (!notFollowedBy(tokens,
["def", "comma", "arrow", "right_brace", "right_square"],
["comma", "arrow", "right_brace", "right_square"],
linenum,
charnum)) {
throw error.JSyntaxError(linenum,
charnum,
"def " + identifier.val + " must not be followed by " + fst(tokens)[0]);
}
return new typ.Def(identifier, parse(tokens));
var bound = parse(tokens);
if (bound.exprType === "Definition" ||
bound.exprType === "FunctionDefinition") {
throw error.JSyntaxError(linenum,
charnum,
"A definition cannot be the value of a binding");
}
return new typ.Def(identifier, bound);
}
}
@ -517,9 +537,9 @@ function parseFull(tokenized) {
process.exit(1);
}
}
//console.log(parseFull(tokenizer.tokenize(istr)).map(pprint.pprint).join("\n"));
console.log(parseFull(tokenizer.tokenize(istr)).map(pprint.pprint).join("\n"));
//console.log(tokenizer.tokenize(istr));
console.log(parseFull(tokenizer.tokenize(istr)));
//console.log(parseFull(tokenizer.tokenize(istr)));
//module.exports = {parse : tool.compose(parseFull, tokenizer.tokenize) };

5
pprint.js

@ -55,6 +55,11 @@ function pprint(expr) {
return "[]";
else if (expr.exprType === "Unary")
return "("+expr.op.ident+" "+pprint(expr.val)+")";
else if (expr.exprType === "Let")
return "let {" + expr.pairs.map(
function (v) {
return pprint(v)
}).join(" ; ") + "} in " + pprint(expr.body);
}
module.exports = {pprint : pprint};

3
representation.js

@ -215,4 +215,5 @@ module.exports =
DefFunc : DefFunc,
UnaryOp : UnaryOp,
Nil : Nil,
LetExp : LetExp}
LetExp : LetExp
}

26
test.jl

@ -44,12 +44,22 @@ def (splitHelp acc xs ys)
def (splitxs xs)
(splitHelp [] xs xs)
def r def
{
a = 4
}
a
def main
((print (testUnary 6)) >>
if False
then
undefined
else fileLines
>>
(print
(splitxs [12,3,4,56])))
let {
unary = (print (testUnary 6))
splitted = def {
xs = (fst (splitxs [12,3,4,56]))
} (xs ++ [0,9])
}
if False
then undefined
else
(unary >>
fileLines >>
(print splitted))

Loading…
Cancel
Save