Skip to content

Commit

Permalink
merge medot, inledning
Browse files Browse the repository at this point in the history
  • Loading branch information
northOfThule committed Mar 18, 2010
2 parents f833926 + 54b4f1f commit 1304140
Show file tree
Hide file tree
Showing 8 changed files with 238 additions and 94 deletions.
11 changes: 7 additions & 4 deletions Prelude.hs
@@ -1,11 +1,14 @@
module Prelude where {
infixl 6 +;
infixl 6 -;
infixl 7 *;
infixr 0 $;
infixr 9 .;

($) f x = f x;
(.) f g = \x -> f $ g x;

map f [] = [];
map f (x:xs) = f x : map f xs;

id x = x;

fix f = let x = f x in x
fix f = let { x = f x; } in x;
}
63 changes: 50 additions & 13 deletions haskell.ast.js
Expand Up @@ -34,7 +34,7 @@
| Let Pattern Expression Expression
| Case Expression [(Pattern, Expression)]
| VariableLookup Identifier
| Primitive Function
| Primitive Function
*/

ast.Expression = function(){};
Expand Down Expand Up @@ -83,7 +83,9 @@
this.declr = declr;
this.expr = expr;
this.eval = function(env) {
return this.expr.eval(env.substitute(this.declr.pattern, new interpreter.Closure(env, this.declr.expression)));
var newEnv = env.derive();
newEnv.patternBind(this.declr.pattern, new interpreter.Closure(newEnv, this.declr.expression));
return this.expr.eval(newEnv);
};
};
ast.Case = function(expr, cases) {
Expand All @@ -94,14 +96,14 @@
this.cases = cases;
this.eval = function(env) {
expr = new interpreter.Closure(env, this.expr);
for (i in this.cases) {
for (var i in this.cases) {
newEnv = env.derive();
if (this.cases[i][0].match(newEnv, expr)) {
return new interpreter.Closure(this.cases[i][1], newEnv);
return new interpreter.Closure(newEnv, this.cases[i][1]);
};
};
alert("No matching clause");
};
alert("No matching clause");
};
ast.VariableLookup = function(identifier) {
expectTypeOf(identifier, "string");
Expand Down Expand Up @@ -145,11 +147,16 @@
expectTypeOf(num, "number");
this.type = "Num";
this.num = num;

this.equals = function(n) {
return this.num == n.num;
};
};

ast.Num.prototype = new ast.Value();
/*
data Declaration = Variable Pattern Expression
| Data Identifier [Constructor]
*/

ast.Declaration = function(){};
Expand All @@ -162,7 +169,28 @@
this.expression = expression;
};

ast.Data = function(identifier, constructors) {
expectTypeOf(identifier, "string");
expectTypeArray(constructors, ast.Constructor);
this.type = "Data";
this.identifier = identifier;
this.constructors = constructors;
};

ast.Variable.prototype = new ast.Declaration();
ast.Data.prototype = new ast.Declaration();


/*
data Constructor = Constructor Identifier Integer
*/
ast.Constructor = function(identifier, num) {
expectTypeOf(identifier, "string");
expectTypeOf(num, "number");
this.type = "Constructor";
this.identifier = identifier;
this.number = num;
};

/*
Pattern = Constructor Identifier [Pattern]
Expand All @@ -173,10 +201,10 @@

ast.Pattern = function(){};

ast.Constructor = function(identifier, patterns) {
ast.PatternConstructor = function(identifier, patterns) {
expectTypeOf(identifier, "string");
expectArrayType(patterns, ast.Pattern);
this.type = "Constructor";
//expectArrayType(patterns, ast.Pattern);
this.type = "PatternConstructor";
this.identifier = identifier;
this.patterns = patterns;
this.match = function(env, expr) {
Expand Down Expand Up @@ -232,19 +260,28 @@
this.type = "ConstantPattern";
this.value = value;
this.match = function(env, expr) {
while(expr.type!="Constant") {
while(expr.type!="ConstantThunk") {
expr = expr.force();
};
return (this.value==expr.value);
return (this.value.equals(expr.value));
};
this.vars = function() {
return [];
};
};
ast.Wildcard = function() {
this.type = "Wildcard";
this.match = function(env, expr) {
return true;
};
this.vars = function() {
return [];
};
};

ast.Constructor.prototype = new ast.Pattern();
ast.PatternConstructor.prototype = new ast.Pattern();
ast.VariableBinding.prototype = new ast.Pattern();
ast.Combined.prototype = new ast.Pattern();
ast.ConstantPattern.prototype = new ast.Pattern();

ast.ConstantPattern.prototype = new ast.Pattern();
ast.Wildcard.prototype = new ast.Pattern();
})(haskell.ast,haskell.interpreter);
29 changes: 20 additions & 9 deletions haskell.hiji.js
@@ -1,17 +1,16 @@
// TODO :: FOKUS NÄR MAN KLICKAR I DEN SVARTA RUTAN!!!


var ENTER = '13';
var UP = '38';
var DOWN = '40';

(function($){


var evaluateHaskell = function(line, env)
{
ast = haskell.parser.parse(line).ast;
console.log("%o", ast);
ast = haskell.parser.parse(line).ast;
if (ast == undefined){
return "Syntax Error";
}
console.log("%o", ast);
return haskell.interpreter.eval(ast, env);
};
var makeModules = function(modules){
Expand Down Expand Up @@ -39,12 +38,22 @@ var DOWN = '40';
var hiss = new historry;
// load history from cookie
hiss_cookie = $.cookie("hiss");
if(hiss_cookie != null)
if(hiss_cookie != null){
hiss.history_array = hiss_cookie.split(",");
}

var env = new haskell.interpreter.RootEnv();
haskell.interpreter.primitives(env);



// ladda prelude

$.get('Prelude.hs', function(prelude_data) {
var ast = haskell.parser.parse(prelude_data).ast;
haskell.interpreter.prepare(ast, env);
});

modules[0] = "Prelude";
modules[1] = "Control.Monad";
this.html("<ol>" + makeInput(modules) + "</ol>");
Expand All @@ -65,7 +74,6 @@ var DOWN = '40';
// history
hiss.addHistory(line);
$.cookie("hiss", hiss.history_array.toString(), {expires: 3 });

input.attr("value","");
try {
var newLine = makeEntered(modules, line);
Expand All @@ -90,7 +98,7 @@ var DOWN = '40';
// historry-class with nice name
// !!!WARNING!!! NICE NAME
historry = function (){
this.pointer = 0;
this.pointer = -1;
this.history_array = new Array();
this.addHistory = function(input){
this.history_array.unshift(input);
Expand All @@ -115,3 +123,6 @@ historry = function (){
};

};



46 changes: 41 additions & 5 deletions haskell.interpreter.js
Expand Up @@ -6,6 +6,12 @@
var b = forceTo(env.lookup("b"), "ConstantThunk");
return new interpreter.ConstantThunk(new ast.Num(a.value.num+b.value.num));
}));
env.bind("-", createPrimitive(env, ["a", "b"],
function(env) {
var a = forceTo(env.lookup("a"), "ConstantThunk");
var b = forceTo(env.lookup("b"), "ConstantThunk");
return new interpreter.ConstantThunk(new ast.Num(a.value.num-b.value.num));
}));
env.bind("*", createPrimitive(env, ["a", "b"],
function(env) {
var a = forceTo(env.lookup("a"), "ConstantThunk");
Expand All @@ -19,14 +25,28 @@
return new interpreter.Data("()", []);
}));
};

// Creates env from an ast and returns it !
interpreter.prepare = function(astt, env) {
for (var i in astt.declarations) {
var decl = astt.declarations[i];
if (decl.type=="Variable") {
env.patternBind(decl.pattern, new interpreter.Closure(env, decl.expression));
}
else if (decl.type=="Data") {
for (var i in decl.constructors) {
constr = decl.constructors[i];
env.bind(constr.identifier, createDataConstructor(env, constr));
};
};
};
return env;
};

interpreter.execute = function(astt) {
var env = new interpreter.RootEnv();
// Only fun defs atm
for (i in astt.declarations) {
var decl = astt.declarations[i];
env.patternBind(decl.pattern, new interpreter.Closure(env, decl.expression));
};
interpreter.prepare(astt, env);
interpreter.primitives(env);
return env.lookup("main").force();
};
Expand All @@ -39,11 +59,27 @@
function createPrimitive(env, args, func) {
var expr = new ast.Primitive(func);
var argsR = args.reverse();
for (i in argsR) {
for (var i in argsR) {
expr = new ast.Lambda(new ast.VariableBinding(argsR[i]), expr);
};
return new interpreter.Closure(env, expr);
};
function createDataConstructor(env, constr) {
var ident = constr.identifier;
var num = constr.number;
var args = [];
for (var i = 0; i<num; i++) {
args[i] = "__p" + i;
};
var prim = function(env) {
var givenArgs=[];
for (i in args) {
givenArgs[i] = env.lookup(args[i]);
};
return new interperter.Data(ident, givenArgs);
};
return createPrimitive(env, args, prim);
};
function forceTo(thunk, type) {
while(thunk.type!=type) {
thunk=thunk.force();
Expand Down

0 comments on commit 1304140

Please sign in to comment.