Permalink
Browse files

Merge branch 'master' of github.com:johang88/haskellinjavascript

  • Loading branch information...
2 parents 6133fd1 + 301d982 commit 4ea7538eb46c110e018986a10c0e466e5e477bd4 Mattis Jeppsson committed May 29, 2010
Showing with 247 additions and 44 deletions.
  1. +47 −8 haskell.ast.js
  2. +20 −13 haskell.hiji.js
  3. +65 −0 haskell.hiji.primitives.js
  4. +1 −1 haskell.interpreter.js
  5. +107 −18 haskell.parser.js
  6. +1 −1 haskell.typechecker.js
  7. +1 −0 hiji.html
  8. +5 −3 hs/Prelude.hs
View
@@ -27,6 +27,42 @@
Import = Import Identifier VisibleNames
| ImportQualified Identifer VisibleNames Identifier
*/
+
+ /*
+ data Type = TypeVariable Identifier
+ | TypeConstructor Identifier
+ | TypeApplication Type Type
+ | TypeTupple Int
+ */
+
+ ast.Type = function() {};
+
+ ast.TypeVariable = function(name) {
+ expectTypeOf(name, "string");
+ this.name = name;
+ };
+ ast.TypeVariable.prototype = new ast.Type();
+
+ ast.TypeConstructor = function(name) {
+ expectTypeOf(name, "string");
+ this.name = name;
+ };
+ ast.TypeConstructor.prototype = new ast.Type();
+
+ ast.TypeApplication = function(t1, t2) {
+ expectType(t1, ast.Type);
+ expectType(t2, ast.Type);
+ this.t1 = t1;
+ this.t2 = t2;
+ };
+ ast.TypeApplication.prototype = new ast.Type();
+
+ ast.TypeTupple = function(size) {
+ expectTypeOf(size, "number");
+ this.size = size;
+ };
+ ast.TypeTupple.prototype = new ast.Type();
+
/*
data Expression = Constant Value
@@ -53,7 +89,7 @@
return this.desugar().stringify();
};
ast.Expression.prototype.desugar = function() {
- return this;
+ return undefined;
};
ast.Constant = function(value) {
@@ -422,7 +458,7 @@
/*
data Declaration = Variable Pattern Expression
| Function Identifier [Pattern] [(Guard, Expression)]|Expression
- | Data Identifier [Constructor]
+ | Data Identifier [TVar] [Constructor]
*/
ast.Declaration = function(){};
@@ -438,12 +474,14 @@
return this.pattern.stringify() + " = " + this.expression.stringify();
};
};
-
- ast.Data = function(identifier, constructors) {
+
+ ast.Data = function(identifier, tvars, constructors) {
expectTypeOf(identifier, "string");
+ expectTypeArray(tvars, ast.TypeVariable);
expectTypeArray(constructors, ast.Constructor);
this.type = "Data";
this.identifier = identifier;
+ this.tvars = tvars;
this.constructors = constructors;
};
@@ -486,14 +524,15 @@
ast.Function.prototype = new ast.Declaration();
/*
- data Constructor = Constructor Identifier Integer
+ data Constructor = Constructor Identifier [Type]
*/
- ast.Constructor = function(identifier, num) {
+
+ ast.Constructor = function(identifier, types) {
expectTypeOf(identifier, "string");
- expectTypeOf(num, "number");
+ expectTypeArray(types, ast.Type);
this.type = "Constructor";
this.identifier = identifier;
- this.number = num;
+ this.types = types;
};
/*
View
@@ -23,14 +23,18 @@ commands[":type"] = "TYPE";
if (ast == undefined){
return "Syntax Error";
}
- console.log("%o", ast);
if (ast.type == "DoExpr") {
ast = new haskell.ast.DoExpr(new haskell.ast.Application(new haskell.ast.VariableLookup("hijiOutputLine#"), ast.expr));
}
var doexpr = new haskell.ast.Do([ast,
- new haskell.ast.DoExpr(new haskell.ast.VariableLookup("hijiContinuation#"))
- ]);
- return haskell.interpreter.eval(doexpr, env);
+ new haskell.ast.DoExpr(new haskell.ast.Primitive(
+ function(env) {
+ return new haskell.interpreter.Data("IO", [new haskell.interpreter.HeapPtr(env)]);
+ }
+ ))]);
+ console.log("%o", doexpr);
+ var res = haskell.interpreter.eval(doexpr, env);
+ return res.ptrs[0].dereference();
};
var makeModules = function(modules){
return "<ul class='modules'><li>" + modules.join("</li><li>") + "</li></ul>";
@@ -100,6 +104,7 @@ commands[":type"] = "TYPE";
}
input.attr("value","");
+ $('.input', this).replaceWith(makeEntered(modules, line));
if(isCommand(line)){
runCommand(line, input, line);
}else
@@ -109,15 +114,13 @@ commands[":type"] = "TYPE";
// Global variable:
printArea = $("ol", this);
env = evaluateHaskell(line, env);
-
- // var output = makeOutput(result);
- // $('.input', this).after(output).replaceWith(newLine);
- $("ol",this).append(makeInput(modules));
+ console.log("%o", env);
}
catch(e) {
console.log("%o", e);
};
}
+ $("ol",this).append(makeInput(modules));
//set focus
$("input:text:visible:first").focus();
@@ -211,11 +214,15 @@ commands[":type"] = "TYPE";
$("ol").append(makeInput(modules));
} else if (commands[command] == "TYPE") {
var arg = trim(input.substr(command.length));
- var ast = haskell.parser.parse(arg).ast;
- var type = ast.infer(/* some env */);
- var newLine = ast.stringify() + " :: " + type.stringify();
- $('.input').after(output).replaceWith(newLine);
- $("ol").append(makeInput(modules));
+ var ast = haskell.parser.parse('{' + arg + '}').ast.expr;
+ var tc = haskell.typechecker;
+ var infered = ast.infer(new tc.Environment(new tc.Assumps(), new tc.Subst(), new tc.NameGen()));
+ var predsString = infered.preds.map(function(p) { return p.toString(); }).join(", ");
+ if (predsString.length > 0) {
+ predsString = "(" + predsString + ") => ";
+ }
+ var newLine = ast.stringify() + " :: " + predsString + infered.type.toString();
+ $("ol").append(makeOutput(newLine));
}
}
};
View
@@ -0,0 +1,65 @@
+(function(primitives, ast, interpreter){
+
+ var showResult = function(result) {
+ if (result.type == "Data") {
+ var str = result.identifier;
+ var op = " ";
+
+ if (str == "I#") {
+ str = "";
+ } else if (str == ":") {
+ str = "";
+ op = ",";
+ }
+
+ if (result.ptrs) {
+ var first = true;
+ for (var i = 0; i < result.ptrs.length; i++) {
+ if (str.length == 0 && first) {
+ str = showResult(result.ptrs[i].dereference());
+ if (typeof str.str != "undefined")
+ str = str.str;
+ first = false;
+ } else {
+ var res = showResult(result.ptrs[i].dereference());
+ if (typeof res.str != "undefined")
+ res = res.str;
+ str = str + op + res;
+ }
+ }
+ }
+
+ return { str: str, isList: op == "," };
+ } if (result.force) {
+ return result.force();
+ } else if (result.ptrs) {
+ return result.ptrs[0].dereference();
+ } else {
+ return result;
+ }
+ };
+
+
+ primitives.initHiji = function(env) {
+ env.bind("hijiContinuation#", primitives.createPrimitive(env, 0,
+ function(env, args) {
+ return new interpreter.Data("IO", [new interpreter.HeapPtr(env)]);
+ }));
+
+ // hijiOutputLine# :: a -> IO ()
+ env.bind("hijiOutputLine#", primitives.createPrimitive(env, 1,
+ function(env, args) {
+ var arg = args[0];
+ var result = showResult(arg);
+ if (result.isList) {
+ result = result.str;
+ result = result.substring(0, result.length - 3);
+ result = "[" + result + "]";
+ } else if (typeof result.str != "undefined") {
+ result = result.str;
+ }
+ printArea.append($("<li class='output'></li>").text(result.toString()));
+ return new interpreter.Data("IO", [new interpreter.HeapPtr(new interpreter.Closure(env, new ast.VariableLookup("()")))]);
+ }));
+ };
+})(haskell.primitives, haskell.ast, haskell.interpreter);
View
@@ -31,7 +31,7 @@
else if (decl.type=="Data") {
for (var i in decl.constructors) {
constr = decl.constructors[i];
- env.bind(constr.identifier, primitives.createDataConstructorKludge(env, constr.identifier, constr.number));
+ env.bind(constr.identifier, primitives.createDataConstructorKludge(env, constr.identifier, constr.types.length));
}
}
}
Oops, something went wrong.

0 comments on commit 4ea7538

Please sign in to comment.