Comparing version 0.2.0-alpha1 to 0.2.0-alpha2
{ "name" : "magnet", | ||
"description": "A duck-typed, object-oriented, syntax-driven and potentially awesome programming language.", | ||
"keywords" : ["language", "programming language", "syntax sugar", "duck-typed", "interpreter", "parser", "object-oriented"], | ||
"homepage": "http://github.com/marcelklehr/magnet", | ||
"repository" : { "type" : "git", "url" : "http://github.com/marcelklehr/magnet.git" }, | ||
"author": "Marcel Klehr <mklehr@gmx.net>", | ||
"licenses": ["MIT"], | ||
"bugs": { "url" : "http://github.com/marcelklehr/magnet/issues" }, | ||
@@ -8,0 +8,0 @@ "engines": { "node": ">= 0.6.0" }, |
@@ -0,1 +1,26 @@ | ||
2012-05-31: Marcel Klehr <mklehr@gmx.net>: Update sample to test Timer | ||
2012-05-31: Marcel Klehr <mklehr@gmx.net>: Fix env.events.unblock | ||
2012-05-31: Marcel Klehr <mklehr@gmx.net>: Adjust stdlib to newest ferrite.lib API | ||
2012-05-31: Marcel Klehr <mklehr@gmx.net>: native Scopes for NativeFunctions | ||
2012-05-31: Marcel Klehr <mklehr@gmx.net>: - fix async auto-terminate behaviour - load libs into nativeScope instead of global - extend env.events | ||
2012-05-31: Marcel Klehr <mklehr@gmx.net>: new Library API | ||
2012-05-31: Marcel Klehr <mklehr@gmx.net>: Turn ferrite asyncronous | ||
2012-05-31: Marcel Klehr <mklehr@gmx.net>: Implement event management | ||
2012-05-31: Marcel Klehr <mklehr@gmx.net>: throw unexpected errors normally | ||
2012-05-31: Marcel Klehr <mklehr@gmx.net>: Introduce Library API | ||
2012-05-30: Marcel Klehr <mklehr@gmx.net>: Introduce ruby-like string concatentation | ||
2012-05-30: Marcel Klehr <mklehr@gmx.net>: Adjust behaviour of Obj.copy for Lists | ||
2012-05-30: Marcel Klehr <mklehr@gmx.net>: Mention current scope in stack trace | ||
2012-05-30: Marcel Klehr <mklehr@gmx.net>: Handle non-magnet Errors | ||
2012-05-30: Marcel Klehr <mklehr@gmx.net>: Use calcLineNo() for getLineExcerpt() to handle undefined offset | ||
2012-05-29: Marcel Klehr <mklehr@gmx.net>: add ferrite/error.js to makefile | ||
2012-05-29: Marcel Klehr <mklehr@gmx.net>: Fix puts to provide error offset | ||
2012-05-29: Marcel Klehr <mklehr@gmx.net>: Fix calcLineNo for undefined offset | ||
2012-05-29: Marcel Klehr <mklehr@gmx.net>: Introduce stack trace | ||
2012-05-29: Marcel Klehr <mklehr@gmx.net>: Introduce Runtime Errors | ||
2012-05-29: Marcel Klehr <mklehr@gmx.net>: More beautiful error reporting | ||
2012-05-29: Marcel Klehr <mklehr@gmx.net>: Refactor nil | ||
2012-05-28: Marcel Klehr <mklehr@gmx.net>: Update README (installation instructions) | ||
2012-05-28: Marcel Klehr <mklehr@gmx.net>: Add github home to package.json | ||
2012-05-28: Marcel Klehr <mklehr@gmx.net>: Fix package.json | ||
2012-05-28: Marcel Klehr <mklehr@gmx.net>: Release 0.2.0-alpha1 | ||
@@ -2,0 +27,0 @@ 2012-05-28: Marcel Klehr <mklehr@gmx.net>: npm support |
@@ -12,4 +12,4 @@ #!/usr/bin/env node | ||
* | ||
* Build date: @DATE | ||
* Commit: @COMMIT | ||
*/ | ||
@@ -1,7 +0,11 @@ | ||
var ferrite = require('../ferrite'); | ||
var ferrite = require('../ferrite'), | ||
stdlib = require('../stdlib'); | ||
fs = require('fs'), | ||
b2mb = function(b) { | ||
return ((b / Math.pow(2, 10))/ Math.pow(2, 10)).toFixed(2) + ' MB'; | ||
}; | ||
/* Interpret a file from the command line*/ | ||
try { | ||
var str = require('fs').readFileSync(process.argv[2], 'utf8'); | ||
var file = fs.realpathSync(process.argv[2]); | ||
var str = fs.readFileSync(file, 'utf8'); | ||
} catch(e) { | ||
@@ -12,23 +16,29 @@ console.log('No or invalid input file'); | ||
//var stdlib = new ferrite.Library; | ||
// define stdlib | ||
// ... | ||
fs.watch(file,function(){});// block node from terminating | ||
var program = ferrite.interpret(str/*, stdlib*/); | ||
var startmemory = process.memoryUsage().heapUsed; | ||
console.time('# Execution time'); | ||
program.errors.forEach(function(err) { | ||
console.log('\r\n'); | ||
ferrite.interpret(str, stdlib, function(errors, env){ | ||
errors.forEach(function(err) { | ||
console.log('\r\n'); | ||
var padding = ferrite.repeatString(' ', err.col-1); | ||
console.log(file+':'+err.line); | ||
console.log('\t'+err.excerpt); | ||
console.log('\t'+padding + '^'); | ||
console.log(err.msg); | ||
if(err.backtrace) { | ||
err.backtrace.forEach(function(call) { | ||
console.log(' at '+call.caller+' (line '+call.at+')'); | ||
}); | ||
} | ||
}); | ||
console.log(process.argv[2]+':'+err.line); | ||
console.log('\t'+err.excerpt); | ||
// post execution notes | ||
console.timeEnd('# Execution time'); | ||
console.log('# Heap size: ', env.heap.length); | ||
console.log('# Memory usage: ', b2mb(process.memoryUsage().heapUsed - startmemory)); | ||
var padding = ferrite.repeatString(' ', err.col-1); | ||
console.log('\t'+padding + '^'); | ||
console.log('Parse Error in line ' + err.line + ', unexpected token '+JSON.stringify(err.excerpt[err.col-1])+'\r\nexpecting ' + err.expected) ; | ||
}); | ||
if(program.errors.length > 1) { | ||
console.log('__'); | ||
program.trace.backtrace(); | ||
} | ||
process.exit();// terminate process | ||
}); |
@@ -10,8 +10,4 @@ /*! | ||
* | ||
* based upon: | ||
* JS/CC - A LALR(1) Parser Generator written in JavaScript | ||
* Copyright (c) 2007, 2008 Jan Max Meyer | ||
* | ||
* Build date: @DATE | ||
* Commit: @COMMIT | ||
*/ | ||
function Environment() { | ||
this.heap = {length:1, 0:new Nil}; // 0 : nil | ||
this.trace = new Trace; | ||
this.gcCounter = 0; | ||
// settings | ||
this.garbage_collection = true; | ||
this.gcInterval = 15000; | ||
this.debuggerOn = false; | ||
this.CYCLE_LIMIT = 10; | ||
this.proto = {}; | ||
this.proto['object'] = Primal.protoObject(this); | ||
this.proto['boolean'] = Primal.protoBoolean(this); | ||
this.proto['function'] = Primal.protoFunction(this); | ||
this.proto['float'] = Primal.protoFloat(this); | ||
this.proto['integer'] = Primal.protoInteger(this); | ||
this.proto['string'] = Primal.protoString(this); | ||
this.proto['list'] = Primal.protoList(this); | ||
if(this.debuggerOn) { | ||
NODE_OP = 0; | ||
var env = this; | ||
this.heap = {length: 1, 0: null}; // 0 : nil | ||
this.gcCounter = 0; | ||
this.events = { | ||
waiting: 0, | ||
block: function env_blockTermination(cb) { | ||
var events = this; | ||
this.waiting++; | ||
return function() { | ||
cb.apply(this, arguments); | ||
events.unblock(); | ||
} | ||
}, | ||
unblock: function() { | ||
env.events.waiting--; | ||
if(env.events.waiting == 0) { | ||
env.emit('end'); | ||
} | ||
} | ||
}; | ||
// settings | ||
this.garbageCollectionOn = true; | ||
this.gcInterval = 15000; | ||
this.debuggerOn = false; | ||
this.CYCLE_LIMIT = 10; | ||
this.proto = {}; | ||
this.proto['object'] = Primal.protoObject(this); | ||
this.proto['boolean'] = Primal.protoBoolean(this); | ||
this.proto['function'] = Primal.protoFunction(this); | ||
this.proto['float'] = Primal.protoFloat(this); | ||
this.proto['integer'] = Primal.protoInteger(this); | ||
this.proto['string'] = Primal.protoString(this); | ||
this.proto['list'] = Primal.protoList(this); | ||
this.heap[0] = new Nil(this); | ||
if(this.debuggerOn) { | ||
NODE_OP = 0; | ||
NODE_ACT = 'NODE_ACT'; | ||
NODE_ACT = 'NODE_ACT'; | ||
NODE_EXPR = 'NODE_EXPR'; | ||
NODE_EXPR = 'NODE_EXPR'; | ||
NODE_INT = 'NODE_INT'; | ||
NODE_FLOAT = 'NODE_FLOAT'; | ||
NODE_STR = 'NODE_STR'; | ||
NODE_BOOL = 'NODE_BOOL'; | ||
NODE_INT = 'NODE_INT'; | ||
NODE_FLOAT = 'NODE_FLOAT'; | ||
NODE_STR = 'NODE_STR'; | ||
NODE_BOOL = 'NODE_BOOL'; | ||
NODE_VAR = 'NODE_VAR'; | ||
NODE_PROP = 'NODE_PROP'; | ||
NODE_IDENT = 'NODE_IDENT'; | ||
NODE_VAR = 'NODE_VAR'; | ||
NODE_PROP = 'NODE_PROP'; | ||
NODE_IDENT = 'NODE_IDENT'; | ||
NODE_FUNC = 'NODE_FUNC'; | ||
NODE_PARAM = 'NODE_PARAM'; | ||
NODE_FUNC = 'NODE_FUNC'; | ||
NODE_PARAM = 'NODE_PARAM'; | ||
NODE_CALL = 'NODE_CALL'; | ||
NODE_ARG = 'NODE_ARG'; | ||
NODE_OBJ = 'NODE_OBJ'; | ||
NODE_PROPDEF= 'NODE_PROPDEF'; | ||
NODE_LIST = 'NODE_LIST'; | ||
NODE_CALL = 'NODE_CALL'; | ||
NODE_ARG = 'NODE_ARG'; | ||
NODE_OBJ = 'NODE_OBJ'; | ||
NODE_PROPDEF= 'NODE_PROPDEF'; | ||
NODE_LIST = 'NODE_LIST'; | ||
OP_NONE = 'OP_NONE'; | ||
OP_ASSIGN = 'OP_ASSING'; | ||
OP_NONE = 'OP_NONE'; | ||
OP_ASSIGN = 'OP_ASSING'; | ||
OP_EQU = 'OP_EQU'; | ||
OP_NEQ = 'OP_NEQ'; | ||
OP_GRT = 'OP_GRT'; | ||
OP_LOT = 'OP_LOT'; | ||
OP_GRE = 'OP_GRE'; | ||
OP_LOE = 'OP_LOE'; | ||
OP_EQU = 'OP_EQU'; | ||
OP_NEQ = 'OP_NEQ'; | ||
OP_GRT = 'OP_GRT'; | ||
OP_LOT = 'OP_LOT'; | ||
OP_GRE = 'OP_GRE'; | ||
OP_LOE = 'OP_LOE'; | ||
OP_ADD = 'OP_ADD'; | ||
OP_SUB = 'OP_SUB'; | ||
OP_DIV = 'OP_DIV'; | ||
OP_MUL = 'OP_MUL'; | ||
OP_NEG = 'OP_NEG'; | ||
OP_ADD = 'OP_ADD'; | ||
OP_SUB = 'OP_SUB'; | ||
OP_DIV = 'OP_DIV'; | ||
OP_MUL = 'OP_MUL'; | ||
OP_NEG = 'OP_NEG'; | ||
OP_OR = 'OP_OR'; | ||
OP_AND = 'OP_AND'; | ||
OP_NOT = 'OP_NOT'; | ||
OP_OR = 'OP_OR'; | ||
OP_AND = 'OP_AND'; | ||
OP_NOT = 'OP_NOT'; | ||
OP_PUTS = 'OP_PUTS'; | ||
OP_TRACE = 'OP_TRACE'; | ||
OP_DEBUG = 'OP_DEBUG'; | ||
OP_RET = 'OP_RET'; | ||
OP_IFELSE = 'OP_IFELSE'; | ||
} | ||
OP_PUTS = 'OP_PUTS'; | ||
OP_TRACE = 'OP_TRACE'; | ||
OP_DEBUG = 'OP_DEBUG'; | ||
OP_RET = 'OP_RET'; | ||
OP_IFELSE = 'OP_IFELSE'; | ||
} | ||
} | ||
Environment.prototype = new(require('events').EventEmitter); | ||
Environment.prototype.constructor = Environment; | ||
Environment.prototype.throw = function env_throw(msg, offset, scope) { | ||
this.emit('error', MagnetError(msg, offset, scope)); | ||
}; | ||
Environment.prototype.debug = function env_debug() { | ||
@@ -114,3 +141,3 @@ if(this.debuggerOn === true) console.log.apply(console, arguments); | ||
Environment.prototype.gc = function env_gc(scope) { | ||
if(this.garbage_collection === false) return; | ||
if(this.garbageCollectionOn === false) return; | ||
if(this.gcCounter < this.gcInterval) return; | ||
@@ -117,0 +144,0 @@ this.debug('-GC-'); |
module.exports.Primal = Primal; // interface for creating magnet objects from javascript values | ||
//module.exports.Library = Library; interface for registering stdlib methods written in javascript | ||
module.exports.Library = Library; // interface for registering stdlib methods written in javascript | ||
@@ -8,16 +8,21 @@ // utility | ||
module.exports.interpret = function interpret(code, lib) { | ||
module.exports.interpret = function interpret(code, libs, cb) { | ||
code += "\r\n"; | ||
var b2mb = function(b) { | ||
return ((b / Math.pow(2, 10))/ Math.pow(2, 10)).toFixed(2) + ' MB'; | ||
}; | ||
var startmemory = process.memoryUsage().heapUsed; | ||
console.time('# Execution time'); | ||
var globalScope = new Scope; | ||
// lib.attach(globalScope); --activate for stdlib support | ||
var nativeScope = new Scope; | ||
nativeScope.meta = {identifier: '<Native>'}; | ||
var globalScope = new Scope(nativeScope, nativeScope); | ||
globalScope.meta = {identifier: '<Global>'}; | ||
var env = globalScope.env; | ||
libs = libs ? libs : []; | ||
libs.forEach(function(lib) { | ||
lib.attach(nativeScope); | ||
}); | ||
var opcode = []; | ||
var err_offsets = new Array(); | ||
var err_lookaheads = new Array(); | ||
var err_offsets = []; | ||
var err_lookaheads = []; | ||
var err_count = 0; | ||
@@ -28,21 +33,33 @@ var errors = []; | ||
for( var i = 0; i < err_count; i++ ) { | ||
var line = code.substr( 0, err_offsets[i] ).split("\n").length; | ||
var line = calcLineNo(code, err_offsets[i]); | ||
errors.push({ | ||
line : line, | ||
expected : err_lookaheads[i].join(), | ||
excerpt : code.substr( 0, err_offsets[i] ).split("\n").pop() + code.substr( err_offsets[i], 250 ).split("\n")[0], | ||
col : code.substr( 0, err_offsets[i] ).split("\n").pop().length+1 | ||
col : getLineCol(code, err_offsets[i]), | ||
msg : 'Parse Error: unexpected token '+JSON.stringify(code[err_offsets[i]])+' expecting ' + err_lookaheads[i].map(JSON.stringify).join(' or '), | ||
excerpt : getLineExcerpt(code, err_offsets[i]) | ||
}); | ||
} | ||
return {errors: errors, trace: globalScope.env.trace}; | ||
return cb(errors, globalScope.env); | ||
} | ||
var ret = globalScope.executeTokenList(opcode); // the returned value | ||
globalScope.env.on('end', function() { | ||
cb([], globalScope.env); | ||
}); | ||
// post execution notes | ||
console.timeEnd('# Execution time'); | ||
console.log('# Heap size: ', globalScope.env.heap.length); | ||
console.log('# Memory usage: ', b2mb(process.memoryUsage().heapUsed - startmemory)); | ||
globalScope.env.on('error', function(err) { | ||
var trace = e.scope.backtrace().map(function(call) { | ||
return {caller: call.caller, at: call.at ? calcLineNo(code, call.at) : '<native>'}; | ||
}); | ||
trace.unshift({caller: e.scope.meta.identifier, at: calcLineNo(code, e.offset)}); | ||
cb([{ | ||
msg: 'Runtime Error: '+e.message, | ||
line: calcLineNo(code, e.offset), | ||
col: getLineCol(code, e.offset), | ||
excerpt: getLineExcerpt(code, e.offset), | ||
backtrace: trace | ||
}], globalScope.env); | ||
}); | ||
return {errors: errors, trace: globalScope.env.trace}; | ||
var ret = globalScope.executeTokenList(opcode); // the returned value | ||
if(env.events.waiting == 0) env.emit('end'); | ||
}; |
/*** LIBRARY ***/ | ||
function Library() { } | ||
function Library(name, constructor) { | ||
this.name = name; | ||
this.methods = {}; | ||
this.properties = {}; | ||
this.constructor = constructor; | ||
} | ||
Library.attach = function(scope) { | ||
Library.prototype.attach = function(scope) { | ||
var lib = this; | ||
var env = scope.env; | ||
var obj = env.resolve(Primal.Object(env)); | ||
this.constructor.call({ | ||
method: function(name, func) { | ||
if(!(typeof(func) == "function")) throw new Error('Trying to pass a non-function to Library.method of '+this.name+'.'); | ||
obj.setPropertyPointer(name, lib.transcript(env, func)); | ||
}, | ||
property: function(name, val) { | ||
obj.setPropertyPointer(name, lib.transcript(env, val)) | ||
} | ||
}, env, obj); | ||
scope.setPropertyPointer(this.name, obj.addr); | ||
}; | ||
Library.registerFunction = function(scope) { | ||
Library.prototype.transcript = function(env, val) { | ||
var pointer = 0; | ||
switch(typeof(val)) { | ||
case "number": | ||
pointer = Primal.Float(env, val); | ||
if(val % 1 == 0) pointer = Primal.Integer(env, val); | ||
break; | ||
case "boolean": | ||
pointer = Primal.Boolean(env, val); | ||
break; | ||
case "string": | ||
pointer = Primal.String(env, val); | ||
break; | ||
case "function": | ||
var lib = this; | ||
pointer = Primal.NativeFunction(env, function() { | ||
var args = [].slice.call(arguments); | ||
args.shift(); // myscope | ||
args = args.map(this.env.resolve.bind(this.env)); | ||
return lib.transcript(this.env, val.apply(this, args)); | ||
}); | ||
break; | ||
case "object": | ||
pointer = this.transcriptObject(env, val); | ||
break; | ||
} | ||
return pointer; | ||
} | ||
}; | ||
/* ... */ | ||
Library.prototype.transcriptObject = function(env, jsObject) { | ||
var pobj = Primal.Object(env); | ||
var obj = env.resolve(pobj); | ||
for(var prop in jsObject) { | ||
var val = jsObject[prop]; | ||
obj.setPropertyPointer(prop, this.transcript(env, val)); | ||
} | ||
return pobj; | ||
} |
/*** NODE ***/ | ||
function Node(type, val, children) { | ||
function Node(type, val, children, offset) { | ||
var node = this; | ||
@@ -9,2 +9,3 @@ | ||
this.children = []; | ||
this.offset = offset; | ||
@@ -20,2 +21,4 @@ if(children) { | ||
var NODE_NIL = -1; | ||
var NODE_OP = 0; | ||
@@ -73,2 +76,2 @@ | ||
var OP_IFELSE = 119; | ||
var OP_IFELSE = 120; | ||
var OP_IFELSE = 120; |
@@ -23,2 +23,11 @@ /*** SCOPE ***/ | ||
Scope.prototype.backtrace = function() { | ||
var trace = []; | ||
if(this.precursor) { | ||
trace.push({caller: this.precursor.meta.identifier || '<Anonymous>', at: this.meta.calledFrom}); | ||
trace = trace.concat(this.precursor.backtrace()); | ||
} | ||
return trace; | ||
}; | ||
Scope.prototype.gc = function(marked) { | ||
@@ -31,3 +40,2 @@ GenericObject.prototype.gc.call(this, marked); | ||
Scope.prototype.getPropertyPointer = function(identifier) { | ||
if(identifier == 'nil') return 0; | ||
if(this.properties[identifier]) return this.properties[identifier]; | ||
@@ -39,3 +47,2 @@ if(this.parent) return this.parent.getPropertyPointer(identifier); | ||
Scope.prototype.setPropertyPointer = function(identifier, addr, recursive_call) { | ||
if(identifier == 'nil') throw new Error('Can\'t assign to nil keyword'); | ||
if(this.parent && !this.properties[identifier] && this.parent.properties[identifier]) return this.parent.setPropertyPointer(identifier, addr, 'recursive'); | ||
@@ -68,2 +75,5 @@ return this.properties[identifier] = addr; | ||
case NODE_NIL: | ||
break; | ||
case NODE_BOOL: | ||
@@ -79,3 +89,19 @@ return Primal.Boolean(this.env, node.value); | ||
case NODE_STR: | ||
return Primal.String(this.env, node.value); | ||
var scope = this; | ||
var str = node.value; | ||
str = str.replace('\\r', "\r"); | ||
str = str.replace('\\n', "\n"); | ||
str = str.replace('\\\r', "\\r"); | ||
str = str.replace('\\\n', "\\n"); | ||
str = '%'+str; // add padding | ||
str = str.replace(/[^\\]#{(.*?)}/gi, function(str, expression, offset) { | ||
var opcode = [], error_offs = []; | ||
var code = '('+expression+')'; | ||
if((err_count = __parse( code, error_offs, [], opcode ) ) > 0) this.env.throw('Syntax Error: String concatentation failed. (Unexpected '+code[error_offs[0]]+')', node.offset+offset+2+error_offs[0], scope); | ||
return str[0]+scope.env.cast('string', scope.env.resolve(scope.execute(opcode[0].value))).getVal(); | ||
}); | ||
str = str.substr(1); // remove padding | ||
str = str.replace('\\#{', "#{"); | ||
return Primal.String(this.env, str); | ||
@@ -127,3 +153,5 @@ | ||
var prop = this.execute(node.children[0]); | ||
return {object: object, property: prop}; | ||
var source = (node.value ? 'Object.' : '')+prop; | ||
if(node.value && node.value.type == NODE_VAR) source = this.execute(node.value.value).source+"."+prop; | ||
return {object: object, property: prop, source: source}; | ||
@@ -148,3 +176,5 @@ case NODE_IDENT: | ||
var addr = this.execute(node.children[0]); | ||
console.log( this.env.cast('string', this.env.resolve(addr) ).getVal() ); | ||
try { | ||
console.log( this.env.cast('string', this.env.resolve(addr) ).getVal() ); | ||
}catch(e){ this.env.throw(e.message, node.offset, this);} | ||
return addr; | ||
@@ -172,3 +202,3 @@ | ||
this.env.resolve(variable.object).setPropertyPointer( variable.property, addr ); | ||
this.env.trace.log( 'assignment: <object>.'+variable.property+' -> '+ this.env.resolve( addr ).dump() ); | ||
this.env.debug( 'assignment: <object>.'+variable.property+' -> '+ this.env.resolve( addr ).dump() ); | ||
return addr; | ||
@@ -200,36 +230,58 @@ | ||
case OP_EQU: | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return obj.callMethod('==', [this.execute( node.children[1] )], this); | ||
try { | ||
return obj.callMethod('==', [this.execute( node.children[1] )], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
case OP_NEQ: | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return this.env.resolve( obj.callMethod( '==' , [this.execute( node.children[1] )], this) ).callMethod('!', [], this); | ||
try { | ||
return this.env.resolve( obj.callMethod( '==' , [this.execute( node.children[1] )], this) ).callMethod('!', [], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
case OP_GRT: | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return obj.callMethod('>', [this.execute( node.children[1] )], this); | ||
try { | ||
return obj.callMethod('>', [this.execute( node.children[1] )], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
case OP_LOT: | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return obj.callMethod('<', [this.execute( node.children[1] )], this); | ||
try { | ||
return obj.callMethod('<', [this.execute( node.children[1] )], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
case OP_GRE: | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return this.env.resolve( obj.callMethod('<', [this.execute( node.children[1] )], this)).callMethod('!',[], this); | ||
try { | ||
return this.env.resolve( obj.callMethod('<', [this.execute( node.children[1] )], this)).callMethod('!',[], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
case OP_LOE: | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return this.env.resolve( obj.callMethod('>', [this.execute( node.children[1] )], this)).callMethod('!', [], this); | ||
try { | ||
return this.env.resolve( obj.callMethod('>', [this.execute( node.children[1] )], this)).callMethod('!', [], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
/* Boolean Operators */ | ||
case OP_OR: | ||
console.log(node.children[0].value); | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return obj.callMethod('||', [this.execute( node.children[1] )], this); | ||
try { | ||
return obj.callMethod('||', [this.execute( node.children[1] )], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
case OP_AND: | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return obj.callMethod('&&', [this.execute( node.children[1] )], this ); | ||
try { | ||
return obj.callMethod('&&', [this.execute( node.children[1] )], this ); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
case OP_NOT: | ||
var obj = this.env.resolve(this.execute( node.children[0] ) ); | ||
return obj.callMethod('!', [], this); | ||
try { | ||
return obj.callMethod('!', [], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
@@ -239,15 +291,29 @@ /* Arithmetic Operatos */ | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return obj.callMethod('+', [this.execute( node.children[1] )], this); | ||
try { | ||
return obj.callMethod('+', [this.execute( node.children[1] )], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
case OP_SUB: | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return obj.callMethod('-', [this.execute( node.children[1] )], this); | ||
try { | ||
return obj.callMethod('-', [this.execute( node.children[1] )], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
case OP_DIV: | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return obj.callMethod('/', [this.execute( node.children[1] )], this); | ||
try { | ||
return obj.callMethod('/', [this.execute( node.children[1] )], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
case OP_MUL: | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return obj.callMethod('*', [this.execute( node.children[1] )], this); | ||
try { | ||
return obj.callMethod('*', [this.execute( node.children[1] )], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
case OP_NEG: | ||
var obj = this.env.resolve(this.execute( node.children[0] )); | ||
return obj.callMethod('*', [this.env.set(Primal.Integer(this.env, -1))], this); | ||
try { | ||
return obj.callMethod('*', [this.env.set(Primal.Integer(this.env, -1))], this); | ||
}catch(e){ this.env.throw(e.message, node.offset, this); } | ||
} | ||
@@ -269,13 +335,13 @@ break; | ||
case NODE_CALL: | ||
var identifier = (node.value.type == NODE_VAR) ? this.execute(node.value.value).property : '<Closure>'; | ||
var identifier = (node.value.type == NODE_VAR) ? this.execute(node.value.value).source : '<Anonymous>'; | ||
var func = this.env.resolve(this.execute(node.value)); | ||
var args = (node.children[0]) ? this.execute(node.children[0]) : []; | ||
var thisvar = (node.value.type === NODE_VAR) ? this.execute(node.value.value).object : this.env.set(this); | ||
if(func instanceof Nil) throw new Error('Trying to call a non-existent function. (identifier: "'+identifier+'")'); | ||
if(func instanceof Nil) this.env.throw('Trying to call a non-existent function.', node.offset, this); | ||
// invoke function | ||
var ret = this.env.cast('function', func).invoke(thisvar, args, this /*callingScope*/); | ||
var ret = this.env.cast('function', func).invoke(thisvar, args, this/*callingScope*/, {calledFrom: node.offset, identifier: identifier} ); | ||
this.env.debug('---'); | ||
if(ret != 0) { | ||
this.env.trace.log( 'function return value: '+identifier+' ( '+args.join(' , ')+' ) -> ' , this.env.resolve(ret).dump() ); | ||
this.env.debug( 'function return value: '+identifier+' ( '+args.join(' , ')+' ) -> ' , this.env.resolve(ret).dump() ); | ||
return ret;// addr | ||
@@ -282,0 +348,0 @@ } |
@@ -8,3 +8,3 @@ // Boolean \\ | ||
// == | ||
object.properties['=='] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['=='] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var equ; | ||
@@ -20,3 +20,3 @@ try { | ||
// || | ||
object.properties['||'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['||'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var or = env.cast('boolean', this).getVal() || env.cast('boolean', env.resolve(obj)).getVal(); | ||
@@ -27,3 +27,3 @@ return Primal.Boolean(env, or); | ||
// && | ||
object.properties['&&'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['&&'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var or = env.cast('boolean', this).getVal() && env.cast('boolean', env.resolve(obj)).getVal(); | ||
@@ -34,3 +34,3 @@ return Primal.Boolean(env, or); | ||
// ! | ||
object.properties['!'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['!'] = Primal.NativeFunction(env, function(myscope) { | ||
var not = !env.cast('boolean', this).getVal(); | ||
@@ -41,3 +41,3 @@ return Primal.Boolean(env, not); | ||
// read | ||
object.properties['read'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['read'] = Primal.NativeFunction(env, function(myscope) { | ||
return Primal.String(env, ( env.cast('boolean', this).getVal() ) ? 'true' : 'false'); | ||
@@ -70,3 +70,3 @@ }); | ||
// decide | ||
object.properties['decide'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['decide'] = Primal.NativeFunction(env, function(myscope) { | ||
return Primal.Boolean(env, bool); | ||
@@ -73,0 +73,0 @@ }); |
@@ -8,3 +8,3 @@ // Float \\ | ||
// == | ||
object.properties['=='] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['=='] = Primal.NativeFunction(env, function(myscope, obj) { | ||
return Primal.Boolean(env, (env.cast('float', this).getVal() == env.cast('float', env.resolve(obj)).getVal())); | ||
@@ -14,3 +14,3 @@ }); | ||
// > | ||
object.properties['>'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['>'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var bool = env.cast('float', this).getVal() > env.cast('float', env.resolve(obj)).getVal(); | ||
@@ -21,3 +21,3 @@ return Primal.Boolean(env, bool); | ||
// < | ||
object.properties['<'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['<'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var bool = env.cast('float', this).getVal() < env.cast('float', env.resolve(obj)).getVal(); | ||
@@ -28,3 +28,3 @@ return Primal.Boolean(env, bool); | ||
// + | ||
object.properties['+'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['+'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
try { | ||
@@ -34,3 +34,3 @@ var sum = env.cast('float', this).getVal() + env.cast('float', env.resolve(obj)).getVal(); | ||
}catch(e) { | ||
return env.resolve(obj).callMethod('+', [object.addr], precScope); | ||
return env.resolve(obj).callMethod('+', [object.addr], myscope); | ||
} | ||
@@ -40,3 +40,3 @@ }); | ||
// - | ||
object.properties['-'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['-'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var sub = env.cast('float', this).getVal() - env.cast('float', env.resolve(obj)).getVal(); | ||
@@ -47,3 +47,3 @@ return Primal.Float(env, sub); | ||
// / | ||
object.properties['/'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['/'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var div = env.cast('float', this).getVal() / env.cast('float', env.resolve(obj)).getVal(); | ||
@@ -54,3 +54,3 @@ return (div % 1 === 0) ? Primal.Integer(env, div) : Primal.Float(env, div); | ||
// * | ||
object.properties['*'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['*'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var mul = env.cast('float', this).getVal() * env.cast('float', env.resolve(obj)).getVal(); | ||
@@ -61,3 +61,3 @@ return (mul % 1 === 0) ? Primal.Integer(env, mul) : Primal.Float(env, mul); | ||
// read | ||
object.properties['read'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['read'] = Primal.NativeFunction(env, function(myscope) { | ||
return Primal.String(env, ''+env.cast('float', this).getVal()+''); | ||
@@ -89,3 +89,3 @@ }); | ||
// calc | ||
object.properties['calc'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['calc'] = Primal.NativeFunction(env, function(myscope) { | ||
return Primal.Float(env, num); | ||
@@ -92,0 +92,0 @@ }); |
@@ -8,3 +8,3 @@ // Function \\ | ||
// * | ||
object.properties['*'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['*'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var count = env.cast('integer', env.resolve(obj)).getVal(); | ||
@@ -19,3 +19,3 @@ var func = env.cast('function', this); | ||
// copy | ||
object.properties['copy'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['copy'] = Primal.NativeFunction(env, function(myscope) { | ||
var obj = new GenericObject(env, this.proto); | ||
@@ -30,3 +30,3 @@ obj.isPrimal = !!this.isPrimal; | ||
} | ||
obj.properties[prop] = env.resolve(this.properties[prop]).callMethod('copy', [], precScope); | ||
obj.properties[prop] = env.resolve(this.properties[prop]).callMethod('copy', [], myscope); | ||
} | ||
@@ -55,3 +55,3 @@ obj.addr = env.set(obj) | ||
object.invoke = function(thisvar, args, callingScope) { | ||
object.invoke = function(thisvar, args, callingScope, metaCall) { | ||
this.env.debug('calling {Function}'); | ||
@@ -61,2 +61,5 @@ | ||
var scope = new Scope(parentScope, callingScope); | ||
scope.meta = metaCall; | ||
// set args | ||
for(var i=0; i < args.length; i++) { | ||
@@ -105,5 +108,7 @@ if(!params[i]) break; | ||
object.invoke = function(thisvar, args, callingScope) { | ||
object.invoke = function(thisvar, args, callingScope, metaCall) { | ||
this.env.debug('Calling {NativeFunction}'); | ||
var ret = func.apply(env.resolve(thisvar), [callingScope].concat(args)); | ||
var scope = new Scope(null, callingScope); | ||
scope.meta = metaCall; | ||
var ret = func.apply(env.resolve(thisvar), [scope].concat(args)); | ||
return (ret) ? ret : 0; | ||
@@ -110,0 +115,0 @@ }; |
@@ -8,3 +8,3 @@ // Integer \\ | ||
// == | ||
object.properties['=='] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['=='] = Primal.NativeFunction(env, function(myscope, obj) { | ||
return Primal.Boolean(env, (env.cast('float', this).getVal() == env.cast('float', env.resolve(obj)).getVal())); | ||
@@ -14,3 +14,3 @@ }); | ||
// > | ||
object.properties['>'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['>'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var bool = env.cast('float', this).getVal() > env.cast('float', env.resolve(obj)).getVal(); | ||
@@ -21,3 +21,3 @@ return Primal.Boolean(env, bool); | ||
// < | ||
object.properties['<'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['<'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var bool = env.cast('float', this).getVal() < env.cast('float', env.resolve(obj)).getVal(); | ||
@@ -28,3 +28,3 @@ return Primal.Boolean(env, bool); | ||
// + | ||
object.properties['+'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['+'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
try { | ||
@@ -34,3 +34,3 @@ var sum = env.cast('float', this).getVal() + env.cast('float', env.resolve(obj)).getVal(); | ||
}catch(e) { | ||
return env.resolve(obj).callMethod('+', [this.addr], precScope); | ||
return env.resolve(obj).callMethod('+', [this.addr], myscope.precursor); | ||
} | ||
@@ -40,3 +40,3 @@ }); | ||
// - | ||
object.properties['-'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['-'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var sub = env.cast('float', this).getVal() - env.cast('float', env.resolve(obj)).getVal(); | ||
@@ -47,3 +47,3 @@ return (sub % 1 === 0) ? Primal.Integer(env, sub) : Primal.Float(env, sub); | ||
// / | ||
object.properties['/'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['/'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var div = env.cast('float', this).getVal() / env.cast('float', env.resolve(obj)).getVal(); | ||
@@ -54,3 +54,3 @@ return (div % 1 === 0) ? Primal.Integer(env, div) : Primal.Float(env, div); | ||
// * | ||
object.properties['*'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['*'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
try { | ||
@@ -60,3 +60,3 @@ var mul = env.cast('float', this).getVal() * env.cast('float', env.resolve(obj)).getVal(); | ||
}catch(e){ | ||
return env.resolve(obj).callMethod('*', [this.addr], precScope); | ||
return env.resolve(obj).callMethod('*', [this.addr], myscope.precursor); | ||
} | ||
@@ -66,3 +66,3 @@ }); | ||
// calc | ||
object.properties['calc'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['calc'] = Primal.NativeFunction(env, function(myscope) { | ||
return Primal.Float(env, parseFloat(env.cast('integer', this).getVal())); | ||
@@ -72,3 +72,3 @@ }); | ||
// loop | ||
object.properties['times'] = Primal.NativeFunction(env, function(precScope, func) { | ||
object.properties['times'] = Primal.NativeFunction(env, function(myscope, func) { | ||
if(!func) return; | ||
@@ -79,3 +79,3 @@ func = env.resolve(func); | ||
var element = Primal.Integer(env, i); | ||
func.invoke(this.addr, [ element ], precScope); | ||
func.invoke(this.addr, [ element ], myscope); | ||
} | ||
@@ -86,3 +86,3 @@ return; | ||
// read | ||
object.properties['read'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['read'] = Primal.NativeFunction(env, function(myscope) { | ||
return Primal.String(env, ''+env.cast('integer', this).getVal()+''); | ||
@@ -114,3 +114,3 @@ }); | ||
// count | ||
object.properties['count'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['count'] = Primal.NativeFunction(env, function(myscope) { | ||
return Primal.Integer(env, num); | ||
@@ -117,0 +117,0 @@ }); |
@@ -12,4 +12,18 @@ // String \\ | ||
// copy | ||
object.properties['copy'] = Primal.NativeFunction(env, function(myscope) { | ||
var obj = new GenericObject(env, this.proto); | ||
obj.isPrimal = !!this.isPrimal; | ||
obj.dump = this.dump; | ||
obj.gc = this.gc; | ||
obj.length = this.length; | ||
for(var prop in this.properties) { | ||
obj.properties[prop] = env.resolve(this.properties[prop]).callMethod('copy', [], myscope); | ||
} | ||
obj.addr = env.set(obj); | ||
return obj.addr; | ||
}); | ||
// count | ||
object.properties['count'] = Primal.NativeFunction(env, function PrimalList_count(precScope) { | ||
object.properties['count'] = Primal.NativeFunction(env, function PrimalList_count(myscope) { | ||
return Primal.Integer(env, this.length); | ||
@@ -19,3 +33,3 @@ }); | ||
// push | ||
object.properties['push'] = Primal.NativeFunction(env, function(precScope /* , obj...*/) { | ||
object.properties['push'] = Primal.NativeFunction(env, function(myscope /* , obj...*/) { | ||
var thisobj = this; | ||
@@ -34,3 +48,3 @@ var args = Array.prototype.slice.call(arguments); | ||
// pop | ||
object.properties['pop'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['pop'] = Primal.NativeFunction(env, function(myscope) { | ||
var last = (this.length > 0) ? this.length-1 : 0; | ||
@@ -44,3 +58,3 @@ var addr = this.getPropertyPointer(last); | ||
// shift | ||
object.properties['shift'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['shift'] = Primal.NativeFunction(env, function(myscope) { | ||
var addr = this.getPropertyPointer(0); | ||
@@ -58,3 +72,3 @@ for(var prop in this.properties) { | ||
// unshift | ||
object.properties['unshift'] = Primal.NativeFunction(env, function(precScope /*, objects */) { | ||
object.properties['unshift'] = Primal.NativeFunction(env, function(myscope /*, objects */) { | ||
var thisobj = this; | ||
@@ -77,3 +91,3 @@ var args = Array.prototype.slice.call(arguments); | ||
// join | ||
object.properties['join'] = Primal.NativeFunction(env, function PrimalList_count(precScope, seperator) { | ||
object.properties['join'] = Primal.NativeFunction(env, function PrimalList_count(myscope, seperator) { | ||
seperator = (seperator) ? env.cast('string', env.resolve(seperator)).getVal() : ''; | ||
@@ -90,3 +104,3 @@ var joined = ''; | ||
// map | ||
object.properties['map'] = Primal.NativeFunction(env, function(precScope, iteratorfunc) { | ||
object.properties['map'] = Primal.NativeFunction(env, function(myscope, iteratorfunc) { | ||
var newlist = env.resolve(Primal.List(env)); | ||
@@ -96,3 +110,3 @@ var i = 0; | ||
if(!isInt(prop)) continue; | ||
var bool = iteratorfunc.invoke(this.addr, [ this.properties[prop], Primal.Integer(prop) ], precScope); | ||
var bool = iteratorfunc.invoke(this.addr, [ this.properties[prop], Primal.Integer(prop) ], myscope); | ||
if(env.cast('bool', env.resolve(bool)).getVal() !== true) newlist[i++] = this.properties[prop]; | ||
@@ -146,7 +160,7 @@ } | ||
// each | ||
object.properties['each'] = Primal.NativeFunction(env, function(precScope, iteratorfunc) { | ||
object.properties['each'] = Primal.NativeFunction(env, function(myscope, iteratorfunc) { | ||
iteratorfunc = env.resolve(iteratorfunc); | ||
for(var prop in this.properties) { | ||
if(!isInt(prop)) continue; | ||
iteratorfunc.invoke(this.addr, [this.properties[prop], Primal.Integer(env, prop)], precScope); | ||
iteratorfunc.invoke(this.addr, [this.properties[prop], Primal.Integer(env, prop)], myscope); | ||
} | ||
@@ -153,0 +167,0 @@ return this.addr; |
// Nil \\ | ||
function Nil() { this.nil = 0; } | ||
function Nil(env) { | ||
this.env = env; | ||
this.addr = 0; | ||
this.properties['=='] = Primal.NativeFunction(env, function(myscope, obj) { | ||
return Primal.Boolean(env, (obj === 0)); | ||
}); | ||
} | ||
Nil.prototype = new GenericObject; | ||
Nil.prototype.constructor = Nil; | ||
Nil.prototype.dump = function() { | ||
@@ -8,2 +17,16 @@ return 'nil'; | ||
Nil.prototype.gc = function() {}; | ||
Nil.prototype.gc = function() { | ||
return; | ||
}; | ||
Nil.prototype.getPropertyPointer = function(property) { | ||
this.env.debug('Nil.getPropertyPointer ', property); | ||
if(this.properties[property]) return this.properties[property]; | ||
if(this.proto) return this.env.resolve(this.proto).getPropertyPointer(property); | ||
throw new Error('Trying to get a property of nil.'); | ||
return 0; | ||
}; | ||
Nil.prototype.setPropertyPointer = function(property, addr) { | ||
throw new Error('Trying to set a property of nil.'); | ||
}; |
@@ -1,2 +0,2 @@ | ||
var Primal = {proto:{}}; | ||
var Primal = {}; | ||
@@ -11,3 +11,3 @@ | ||
// == | ||
object.properties['=='] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['=='] = Primal.NativeFunction(env, function(myscope, obj) { | ||
return Primal.Boolean(env, (this === env.resolve(obj))); | ||
@@ -17,3 +17,3 @@ }); | ||
// fork | ||
object.properties['fork'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['fork'] = Primal.NativeFunction(env, function(myscope) { | ||
var object = new GenericObject(env, env.set(this)); | ||
@@ -25,3 +25,3 @@ object.addr = env.set(object); | ||
// copy | ||
object.properties['copy'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['copy'] = Primal.NativeFunction(env, function(myscope) { | ||
var obj = new GenericObject(env, this.proto); | ||
@@ -31,3 +31,3 @@ obj.isPrimal = !!this.isPrimal; | ||
for(var prop in this.properties) { | ||
obj.properties[prop] = env.resolve(this.properties[prop]).callMethod('copy', [], precScope); | ||
obj.properties[prop] = env.resolve(this.properties[prop]).callMethod('copy', [], myscope); | ||
} | ||
@@ -40,3 +40,3 @@ | ||
// mixin | ||
object.properties['mixin'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['mixin'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
obj = env.resolve(obj); | ||
@@ -98,6 +98,9 @@ for(var prop in obj.properties) { | ||
}; | ||
GenericObject.prototype.callMethod = function(property, args, precScope) { | ||
var method = this.env.resolve(this.getPropertyPointer(property)); | ||
GenericObject.prototype.callMethod = function(property, args, myscope) { | ||
args = (args) ? args : []; | ||
return this.env.cast('function', method).invoke(this.env.set(this), args, precScope); | ||
try { | ||
var method = this.env.resolve(this.getPropertyPointer(property)); | ||
method = this.env.cast('function', method); | ||
}catch(e){ this.env.throw('Trying to call an non-existent method: "'+property+'"');} | ||
return method.invoke(this.env.set(this), args, myscope); | ||
}; | ||
@@ -104,0 +107,0 @@ GenericObject.prototype.dump = function(level, cyclic) { |
@@ -8,3 +8,3 @@ // String \\ | ||
// == | ||
object.properties['=='] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['=='] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var bool; | ||
@@ -19,11 +19,4 @@ try { | ||
// + | ||
object.properties['+'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
var str; | ||
str = env.cast('string', this).getVal() + env.cast('string', env.resolve(obj)).getVal(); | ||
return Primal.String(env, str); | ||
}); | ||
// * | ||
object.properties['*'] = Primal.NativeFunction(env, function(precScope, obj) { | ||
object.properties['*'] = Primal.NativeFunction(env, function(myscope, obj) { | ||
var count = env.cast('integer', env.resolve(obj)).getVal(); | ||
@@ -39,3 +32,3 @@ var fragment = env.cast('string', this).getVal(); | ||
// count | ||
object.properties['count'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['count'] = Primal.NativeFunction(env, function(myscope) { | ||
return Primal.Integer(env, env.cast('string', this).getVal().length); | ||
@@ -45,3 +38,3 @@ }); | ||
// split | ||
object.properties['split'] = Primal.NativeFunction(env, function(precScope, seperator) { | ||
object.properties['split'] = Primal.NativeFunction(env, function(myscope, seperator) { | ||
var string = env.cast('string', this).getVal(); | ||
@@ -78,3 +71,3 @@ seperator = (seperator) ? env.cast('string', env.resolve(seperator)).getVal() : ""; | ||
// read | ||
object.properties['read'] = Primal.NativeFunction(env, function(precScope) { | ||
object.properties['read'] = Primal.NativeFunction(env, function(myscope) { | ||
return Primal.String(env, string); | ||
@@ -81,0 +74,0 @@ }); |
@@ -27,1 +27,14 @@ /** | ||
} | ||
function calcLineNo(source, offset) { | ||
return offset ? source.substr( 0, offset ).split("\n").length : -1; | ||
}; | ||
function getLineExcerpt(source, offset) { | ||
var line = calcLineNo(source, offset); | ||
return (line >= 0) ? source.split("\n")[line-1] : '<No code reference>'; | ||
}; | ||
function getLineCol(source, offset) { | ||
return source.substr( 0, offset ).split("\n").pop().length+1 | ||
}; |
@@ -10,4 +10,4 @@ /*! | ||
* | ||
* Build date: @DATE | ||
* Commit: @COMMIT | ||
*/ | ||
@@ -1,1 +0,53 @@ | ||
var ferrite = require('./ferrite'); | ||
var ferrite = require('./ferrite'), | ||
Library = ferrite.Library, | ||
Primal = ferrite.Primal; | ||
var stdlib = module.exports = []; | ||
// Time \\ | ||
stdlib.push(new Library('Time', function(env, lib) { | ||
var TimeObject = function(miliseconds) { | ||
var date = new Date(miliseconds); | ||
return { | ||
timestamp: function() { return date.getTime();}, | ||
miliseconds: function() { return date.getMilliseconds();}, | ||
seconds: function() { return date.getSeconds();}, | ||
minutes: function() { return date.getMinutes();}, | ||
hours: function() { return date.getHours();}, | ||
day: function() { return date.getDay();}, | ||
date: function() { return date.getDate();}, | ||
month: function() { return date.getMonth()+1;}, | ||
year: function() { return date.getFullYear();}, | ||
}; | ||
}; | ||
this.method('now', function() { | ||
return TimeObject(Date.now()); | ||
}); | ||
this.method('fromTimestamp', function(timestamp) { | ||
return TimeObject(timestamp.env.cast('integer', timestamp).getVal()); | ||
}); | ||
})); | ||
// Timer \\ | ||
stdlib.push(new Library('Timer', function(env, lib) { | ||
lib.setPropertyPointer('wait', Primal.NativeFunction(env, function(myscope, milisecs, cb) { | ||
var milisecs = env.cast('integer', env.resolve(milisecs)).getVal(); | ||
var cb = env.cast('function', env.resolve(cb)); | ||
setTimeout(env.events.block(function() { | ||
cb.invoke(0, [], myscope); | ||
}), milisecs); | ||
})); | ||
lib.setPropertyPointer('interval', Primal.NativeFunction(env, function(myscope, milisecs, cb) { | ||
var milisecs = env.cast('integer', env.resolve(milisecs)).getVal(); | ||
var cb = env.cast('function', env.resolve(cb)); | ||
env.events.block(); | ||
setInterval(function() { | ||
cb.invoke(0, [], myscope, {}); | ||
}, milisecs); | ||
})); | ||
})); |
{ "name" : "magnet", | ||
"description": "A duck-typed, object-oriented, syntax-driven and potentially awesome programming language.", | ||
"keywords" : ["language", "programming language", "syntax sugar", "duck-typed", "interpreter", "parser", "object-oriented"], | ||
"homepage": "http://github.com/marcelklehr/magnet", | ||
"repository" : { "type" : "git", "url" : "http://github.com/marcelklehr/magnet.git" }, | ||
"author": "Marcel Klehr <mklehr@gmx.net>", | ||
"licenses": ["MIT"], | ||
"bugs": { "url" : "http://github.com/marcelklehr/magnet/issues" }, | ||
"engines": { "node": ">= 0.6.0" }, | ||
"preferGlobal": true, | ||
"version": "0.2.0-alpha1", | ||
"version": "0.2.0-alpha2", | ||
"files": ["ferrite.js", "stdlib.js", "CHANGELOG.TXT", "LICENSE", "lib", "bin", "jscc", "build", "makefile"], | ||
@@ -12,0 +12,0 @@ "bin": "./bin/magnet", |
/*! | ||
* Magnet v0.2.0-alpha1 | ||
* Magnet v0.2.0-alpha2 | ||
* Interpreted programming language | ||
@@ -10,5 +10,57 @@ * | ||
* | ||
* Build date: Mon May 28 16:17:07 2012 +0200 | ||
* Commit: 74230a3e9ac6d5cd04a18f9c65c94b3d34bdd006 | ||
*/ | ||
var ferrite = require('./ferrite'); | ||
var ferrite = require('./ferrite'), | ||
Library = ferrite.Library, | ||
Primal = ferrite.Primal; | ||
var stdlib = module.exports = []; | ||
// Time \\ | ||
stdlib.push(new Library('Time', function(env, lib) { | ||
var TimeObject = function(miliseconds) { | ||
var date = new Date(miliseconds); | ||
return { | ||
timestamp: function() { return date.getTime();}, | ||
miliseconds: function() { return date.getMilliseconds();}, | ||
seconds: function() { return date.getSeconds();}, | ||
minutes: function() { return date.getMinutes();}, | ||
hours: function() { return date.getHours();}, | ||
day: function() { return date.getDay();}, | ||
date: function() { return date.getDate();}, | ||
month: function() { return date.getMonth()+1;}, | ||
year: function() { return date.getFullYear();}, | ||
}; | ||
}; | ||
this.method('now', function() { | ||
return TimeObject(Date.now()); | ||
}); | ||
this.method('fromTimestamp', function(timestamp) { | ||
return TimeObject(timestamp.env.cast('integer', timestamp).getVal()); | ||
}); | ||
})); | ||
// Timer \\ | ||
stdlib.push(new Library('Timer', function(env, lib) { | ||
lib.setPropertyPointer('wait', Primal.NativeFunction(env, function(myscope, milisecs, cb) { | ||
var milisecs = env.cast('integer', env.resolve(milisecs)).getVal(); | ||
var cb = env.cast('function', env.resolve(cb)); | ||
setTimeout(env.events.block(function() { | ||
cb.invoke(0, [], myscope); | ||
}), milisecs); | ||
})); | ||
lib.setPropertyPointer('interval', Primal.NativeFunction(env, function(myscope, milisecs, cb) { | ||
var milisecs = env.cast('integer', env.resolve(milisecs)).getVal(); | ||
var cb = env.cast('function', env.resolve(cb)); | ||
env.events.block(); | ||
setInterval(function() { | ||
cb.invoke(0, [], myscope, {}); | ||
}, milisecs); | ||
})); | ||
})); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
387050
8299
1
6