From ea81a8087bcd7953b083a2be9db447f75e7ebf56 Mon Sep 17 00:00:00 2001 From: Joel Martin Date: Wed, 2 Apr 2014 22:23:37 -0500 Subject: All: split types into types, env, printer, core. - types: low-level mapping to the implementation language. - core: functions on types that are exposed directly to mal. - printer: implementation called by pr-str, str, prn, println. - env: the environment implementation - Also, unindent all TCO while loops so that the diff of step4 and step5 are minimized. --- js/types.js | 423 ++++++++++++++---------------------------------------------- 1 file changed, 97 insertions(+), 326 deletions(-) (limited to 'js/types.js') diff --git a/js/types.js b/js/types.js index 18fad0a..7fd2962 100644 --- a/js/types.js +++ b/js/types.js @@ -7,59 +7,17 @@ if (typeof module === 'undefined') { var print = exports.print = function () { console.log.apply(console, arguments); }; } -// General utility functions - -// Clone a function -Function.prototype.clone = function() { - var that = this; - var temp = function () { return that.apply(this, arguments); }; - for( key in this ) { - temp[key] = this[key]; - } - return temp; -}; - -function _clone (obj) { - var new_obj; - switch (obj_type(obj)) { - case 'list': - new_obj = obj.slice(0); - break; - case 'vector': - new_obj = obj.slice(0); - new_obj.__isvector__ = true; - break; - case 'hash-map': - new_obj = {}; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { new_obj[k] = obj[k]; } - } - break; - case 'function': - new_obj = obj.clone(); - break; - default: - throw new Error("clone of non-collection: " + obj_type(obj)); - } - return new_obj; -} - - - - -function nil_Q(a) { return a === null ? true : false; } -function true_Q(a) { return a === true ? true : false; } -function false_Q(a) { return a === false ? true : false; } - -function obj_type(obj) { - if (symbol_Q(obj)) { return 'symbol'; } - else if (list_Q(obj)) { return 'list'; } - else if (vector_Q(obj)) { return 'vector'; } - else if (hash_map_Q(obj)) { return 'hash-map'; } - else if (nil_Q(obj)) { return 'nil'; } - else if (true_Q(obj)) { return 'true'; } - else if (false_Q(obj)) { return 'false'; } - else if (atom_Q(obj)) { return 'atom'; } +// General fucnctions + +function _obj_type(obj) { + if (_symbol_Q(obj)) { return 'symbol'; } + else if (_list_Q(obj)) { return 'list'; } + else if (_vector_Q(obj)) { return 'vector'; } + else if (_hash_map_Q(obj)) { return 'hash-map'; } + else if (_nil_Q(obj)) { return 'nil'; } + else if (_true_Q(obj)) { return 'true'; } + else if (_false_Q(obj)) { return 'false'; } + else if (_atom_Q(obj)) { return 'atom'; } else { switch (typeof(obj)) { case 'number': return 'number'; @@ -70,82 +28,12 @@ function obj_type(obj) { } } -function _pr_str(obj, print_readably) { - if (typeof print_readably === 'undefined') { print_readably = true; } - var _r = print_readably; - var ot = obj_type(obj); - switch (ot) { - case 'list': - var ret = obj.map(function(e) { return _pr_str(e,_r); }); - return "(" + ret.join(' ') + ")"; - case 'vector': - var ret = obj.map(function(e) { return _pr_str(e,_r); }); - return "[" + ret.join(' ') + "]"; - case 'hash-map': - var ret = []; - for (var k in obj) { - ret.push(_pr_str(k,_r), _pr_str(obj[k],_r)); - } - return "{" + ret.join(' ') + "}"; - case 'string': - if (print_readably) { - return '"' + obj.replace(/\\/, "\\\\").replace(/"/g, '\\"') + '"'; - } else { - return obj; - } - case 'nil': - return "nil"; - case 'atom': - return "(atom " + _pr_str(obj.val,_r) + ")"; - default: - return obj.toString(); - } -} - -function pr_str() { - return Array.prototype.map.call(arguments,function(exp) { - return _pr_str(exp, true); - }).join(" "); -} - -function str() { - return Array.prototype.map.call(arguments,function(exp) { - return _pr_str(exp, false); - }).join(""); -} - -function prn() { - print.apply({}, Array.prototype.map.call(arguments,function(exp) { - return _pr_str(exp, true); - })); -} - -function println() { - print.apply({}, Array.prototype.map.call(arguments,function(exp) { - return _pr_str(exp, false); - })); -} - -function with_meta(obj, m) { - var new_obj = _clone(obj); - new_obj.__meta__ = m; - return new_obj; -} - -function meta(obj) { - // TODO: support symbols and atoms - if ((!sequential_Q(obj)) && - (!(hash_map_Q(obj))) && - (!(function_Q(obj)))) { - throw new Error("attempt to get metadata from: " + obj_type(obj)); - } - return obj.__meta__; -} +function _sequential_Q(lst) { return _list_Q(lst) || _vector_Q(lst); } -function equal_Q (a, b) { - var ota = obj_type(a), otb = obj_type(b); - if (!(ota === otb || (sequential_Q(a) && sequential_Q(b)))) { +function _equal_Q (a, b) { + var ota = _obj_type(a), otb = _obj_type(b); + if (!(ota === otb || (_sequential_Q(a) && _sequential_Q(b)))) { return false; } switch (ota) { @@ -154,7 +42,7 @@ function equal_Q (a, b) { case 'vector': if (a.length !== b.length) { return false; } for (var i=0; i' : function(a,b){return a>b;}, - '>=' : function(a,b){return a>=b;}, - '+' : function(a,b){return a+b;}, - '-' : function(a,b){return a-b;}, - '*' : function(a,b){return a*b;}, - '/' : function(a,b){return a/b;}, - 'throw': mal_throw, - 'list': list, 'list?': list_Q, - 'vector': vector, 'vector?': vector_Q, - 'hash-map': hash_map, 'map?': hash_map_Q, - 'assoc': assoc, 'dissoc': dissoc, 'get': get, - 'contains?': contains_Q, 'keys': keys, 'vals': vals, - 'atom': atom, 'atom?': atom_Q, - "deref": deref, "reset!": reset_BANG, "swap!": swap_BANG, - 'sequential?': sequential_Q, 'cons': cons, 'nth': nth, - 'empty?': empty_Q, 'count': count, 'concat': concat, - 'conj': conj, 'first': first, 'rest': rest, - 'apply': apply, 'map': map}; - -exports.ns = types.ns = ns; -exports._pr_str = types._pr_str = _pr_str; -exports.prn = types.prn = prn; -exports.Env = types.Env = Env; - -exports.symbol = types.symbol = symbol; -exports.symbol_Q = types.symbol_Q = symbol_Q; -exports.hash_map = types.hash_map = hash_map; -exports.hash_map_Q = types.hash_map_Q = hash_map_Q; -exports.new_function = types.new_function = new_function; -exports.list = types.list = list; -exports.list_Q = types.list_Q = list_Q; -exports.vector = types.vector = vector; -exports.vector_Q = types.vector_Q = vector_Q; - -exports.sequential_Q = types.sequential_Q = sequential_Q; -exports.cons = types.cons = cons; -exports.concat = types.concat = concat; -exports.first = types.first = first; -exports.rest = types.rest = rest; -exports.apply = types.apply = apply; -exports.map = types.map = map; +function _atom(val) { return new Atom(val); } +function _atom_Q(atm) { return atm instanceof Atom; } + + +// Exports +exports._obj_type = types._obj_type = _obj_type; +exports._sequential_Q = types._sequential_Q = _sequential_Q; +exports._equal_Q = types._equal_Q = _equal_Q; +exports._clone = types._clone = _clone; +exports._nil_Q = types._nil_Q = _nil_Q; +exports._true_Q = types._true_Q = _true_Q; +exports._false_Q = types._false_Q = _false_Q; +exports._symbol = types._symbol = _symbol; +exports._symbol_Q = types._symbol_Q = _symbol_Q; +exports._function = types._function = _function; +exports._function_Q = types._function_Q = _function_Q; +exports._list = types._list = _list; +exports._list_Q = types._list_Q = _list_Q; +exports._vector = types._vector = _vector; +exports._vector_Q = types._vector_Q = _vector_Q; +exports._hash_map = types._hash_map = _hash_map; +exports._hash_map_Q = types._hash_map_Q = _hash_map_Q; +exports._assoc_BANG = types._assoc_BANG = _assoc_BANG; +exports._dissoc_BANG = types._dissoc_BANG = _dissoc_BANG; +exports._atom = types._atom = _atom; +exports._atom_Q = types._atom_Q = _atom_Q; -- cgit v1.2.3