Permalink
Browse files

Merged several changes that have been local to my rocketnia-sites pro…

…ject. Notably, we now avoid global state even at the expense of potential extensibility, there are new tools for asynchronous computation, and we use ECMAScript 5 strict mode.
  • Loading branch information...
1 parent b8bd3fb commit 6e3fa0f2f0cad15862a2729557041677693e9a5d @rocketnia committed Dec 9, 2012
Showing with 1,193 additions and 1,342 deletions.
  1. +92 −74 js/choppascript.js
  2. +1 −58 js/chops-html-last.js
  3. +7 −7 js/chops.html
  4. +44 −54 js/chops.js
  5. +3 −59 js/lathe-html-last.js
  6. +1,046 −1,090 js/lathe.js
View
166 js/choppascript.js 100644 → 100755
@@ -50,7 +50,7 @@ Among other slight differences, ">-" and ">->" don't bind "next".
*/
-//"use strict";
+"use strict";
(function ( topThis, topArgs, body ) { body( topThis, topArgs ); })(
this, typeof arguments === "undefined" ? void 0 : arguments,
@@ -102,7 +102,7 @@ function resplice( elems ) {
};
-my.env = $c.ChopsEnvObj.of( {
+my.env = $c.env( {
// These first few are actually useful.
" block": function ( chops ) {
return unsplice( chops ).join( "" );
@@ -136,15 +136,14 @@ my.env = $c.ChopsEnvObj.of( {
},
">-": function ( chops, env ) {
var bindings = [];
- var locals = $c.ChopsEnvObj.of(
- _.shadow( $c.unwrapChopsEnvObj( env ), {
+ var locals = $c.envShadow( env, {
"<-": function ( chops2, env2 ) {
var param = _.gensym();
bindings.push( { param: param, val: chops2 } );
return param;
}
- } ) );
- return _.foldr(
+ } );
+ return _.arrFoldr(
bindings, $c.parseInlineChops( locals, chops ),
function ( binding, body ) {
var val = $c.parseInlineChops( env, binding.val );
@@ -158,7 +157,7 @@ my.env = $c.ChopsEnvObj.of( {
">->": function ( chops, env ) {
var words = $c.chopTrimTokens( chops, /\s+/g );
var body = $c.parseInlineChops( env, words.pop() );
- return _.foldr( _.pair( words ), body,
+ return _.arrFoldr( _.arrPair( words ), body,
function ( binding, body ) {
var param = binding[ 0 ];
var val = $c.parseInlineChops( env, binding[ 1 ] );
@@ -171,13 +170,12 @@ my.env = $c.ChopsEnvObj.of( {
},
">": function ( chops, env ) {
var words = $c.chopTrimTokens( chops, /\s+/g );
- return _.foldr(
+ return _.arrFoldr(
words, $c.parseInlineChops( env, words.pop() ),
function ( template, next ) {
- var locals = $c.ChopsEnvObj.of(
- _.shadow( $c.unwrapChopsEnvObj( env ), {
+ var locals = $c.envShadow( env, {
"next": function () { return resplice( next ); }
- } ) );
+ } );
return resplice(
$c.parseInlineChops( locals, template ) );
} );
@@ -226,9 +224,7 @@ function eachNonArr( x, func ) {
// TODO: Stop taking up nonconstant stack space.
function process( item ) {
if ( _.likeArray( item ) )
- _.each( item, function ( elem ) {
- func( elem );
- } );
+ _.arrEach( item, process );
else
func( item )
}
@@ -244,19 +240,19 @@ LeadSplit.prototype.init = function ( leads ) {
return this;
};
-function LeadExtendOnly() {}
-LeadExtendOnly.prototype = new Lead();
-LeadExtendOnly.prototype.init = function ( keys, next ) {
+function LeadExtendOtherThan() {}
+LeadExtendOtherThan.prototype = new Lead();
+LeadExtendOtherThan.prototype.init = function ( keys, next ) {
this.keys_ = keys;
this.next_ = next;
return this;
};
-function LeadExtend() {}
-LeadExtend.prototype = new Lead();
-LeadExtend.prototype.init = function ( group, extension ) {
- this.group_ = group;
- this.extension_ = extension;
+function LeadExtendOnly() {}
+LeadExtendOnly.prototype = new Lead();
+LeadExtendOnly.prototype.init = function ( keys, next ) {
+ this.keys_ = keys;
+ this.next_ = next;
return this;
};
@@ -268,6 +264,14 @@ LeadGetAll.prototype.init = function ( groups, then ) {
return this;
};
+function LeadExtend() {}
+LeadExtend.prototype = new Lead();
+LeadExtend.prototype.init = function ( group, extension ) {
+ this.group_ = group;
+ this.extension_ = extension;
+ return this;
+};
+
function toLead( x ) {
// TODO: Make this use constant stack space.
if ( x instanceof Lead )
@@ -278,21 +282,17 @@ function toLead( x ) {
throw new Error();
}
-function objMask( a, b ) {
- return _.objAcc( function ( y ) {
- _.objOwnEach( a, function ( k, v ) {
- if ( _.hasOwn( b, k ) )
- y( k, v );
- } );
- } );
-}
-
my.runExtensions = function ( extensions ) {
var groups = {};
var states = [];
- var visitedStates =
- [ { only: null, lead: toLead( extensions ) } ];
- var anythingGoes = true;
+ var visitedStates = [ { otherThan: {}, only: null,
+ lead: toLead( extensions ) } ];
+ function stateCanExtend( state, groupName ) {
+ var safeKey = "|" + groupName;
+ return !(_.hasOwn( state.otherThan || {}, safeKey )
+ || (state.only !== null
+ && !_.hasOwn( state.only, safeKey )));
+ }
while ( visitedStates.length !== 0 ) {
states = visitedStates;
visitedStates = [];
@@ -301,56 +301,59 @@ my.runExtensions = function ( extensions ) {
var anythingHappenedThisTime = true;
- // TODO: See if this needs to be more efficient.
- if ( anythingGoes
- && _.arrAll( states, function ( state ) {
- return state.only !== null;
- } ) )
- anythingGoes = false;
-
var state = states.shift();
var lead = state.lead;
if ( lead instanceof LeadSplit ) {
_.arrEach( lead.leads_, function ( lead ) {
- visitedStates.push(
- { only: state.only, lead: toLead( lead ) } );
+ visitedStates.push( { otherThan: state.otherThan,
+ only: state.only, lead: toLead( lead ) } );
+ } );
+ } else if ( lead instanceof LeadExtendOtherThan ) {
+ visitedStates.push( state.otherThan !== null ? {
+ otherThan: _.objOwnKeySetOr(
+ state.otherThan, lead.keys_ ),
+ only: null,
+ lead: toLead( lead.next_ )
+ } : {
+ otherThan: null,
+ only:
+ _.objOwnKeySetMinus( state.only, lead.keys_ ),
+ lead: toLead( lead.next_ )
} );
} else if ( lead instanceof LeadExtendOnly ) {
- visitedStates.push( {
- only: state.only === null ? lead.keys_ :
- objMask( state.only, lead.keys_ ),
- lead: lead.next_ } );
- } else if ( lead instanceof LeadExtend ) {
- var safeKey = "|" + lead.group_;
- if ( !(state.only === null
- || _.hasOwn( state.only, safeKey )) )
- throw new Error();
- // TODO: See if this needs to be more efficient.
- groups[ safeKey ] = (groups[ safeKey ] || []).concat(
- [ lead.extension_ ] );
+ visitedStates.push( { otherThan: null,
+ only: state.otherThan !== null ?
+ _.objOwnKeySetMinus(
+ lead.keys_, state.otherThan ) :
+ _.objOwnKeySetMask( state.only, lead.keys_ ),
+ lead: toLead( lead.next_ ) } );
} else if ( lead instanceof LeadGetAll ) {
- if ( anythingGoes
- || _.arrAny( lead.groups_, function ( group ) {
- // TODO: See if this needs to be more
- // efficient. We could replace anythingGoes
- // with a "combinedOnly" variable.
- return _.arrAny(
- states.concat( visitedStates ),
- function ( state ) {
+ var allStates = states.concat( visitedStates );
+ // TODO: See if this needs to be more efficient.
+ if ( _.arrAny( allStates, function ( state ) {
+ return _.arrAny( lead.groups_,
+ function ( group ) {
- return _.hasOwn(
- state.only, "|" + group );
+ return stateCanExtend( state, group );
} );
} ) ) {
anythingHappenedThisTime = false;
visitedStates.push( state );
} else {
- visitedStates.push( { only: state.only,
+ visitedStates.push( { otherThan: state.otherThan,
+ only: state.only,
lead: toLead( lead.then_(
_.arrMap( lead.groups_, function ( g ) {
return groups[ "|" + g ] || [];
} ) ) ) } );
}
+ } else if ( lead instanceof LeadExtend ) {
+ var safeKey = "|" + lead.group_;
+ if ( !stateCanExtend( state, lead.group_ ) )
+ throw new Error();
+ // TODO: See if this needs to be more efficient.
+ groups[ safeKey ] = (groups[ safeKey ] || []).concat(
+ [ lead.extension_ ] );
} else {
throw new Error();
}
@@ -362,9 +365,23 @@ my.runExtensions = function ( extensions ) {
}
return groups;
};
+
+my.extendOtherThan = function ( var_args, then ) {
+ var args = _.arrCut( arguments );
+ var then = args.pop();
+ var keys = {};
+ eachNonArr( args, function ( elem ) {
+ if ( !_.isString( elem ) )
+ throw new Error(
+ "extendOtherThan: Not a string: " +
+ JSON.stringify( elem ) );
+ keys[ "|" + elem ] = 1;
+ } );
+ return new LeadExtendOtherThan().init( keys, then );
+};
my.extendOnly = function ( var_args, then ) {
var args = _.arrCut( arguments );
- var then = args.pop()();
+ var then = args.pop();
var keys = {};
eachNonArr( args, function ( elem ) {
if ( !_.isString( elem ) )
@@ -373,16 +390,17 @@ my.extendOnly = function ( var_args, then ) {
} );
return new LeadExtendOnly().init( keys, then );
};
-my.extend = function ( group, extension ) {
- return new LeadExtend().init( group, extension );
-};
my.getAll = function ( var_args, then ) {
// Accepts any number of strings and looks them up.
var args = _.arrCut( arguments );
var then = args.pop();
- return new LeadGetAll().init( args, function ( groups ) {
- return then.apply( null, groups );
- } );
+ return my.extendOtherThan( args,
+ new LeadGetAll().init( args, function ( groups ) {
+ return then.apply( null, groups );
+ } ) );
+};
+my.extend = function ( group, extension ) {
+ return new LeadExtend().init( group, extension );
};
my.getOne = function ( var_args ) {
@@ -428,7 +446,7 @@ my.getOptional = function ( var_args, then ) {
return my.getAll.apply( null, args.concat( [
function ( var_args ) {
- return then.apply( null, _.arrMap( arguments,
+ return _.funcApply( null, then, _.arrMap( arguments,
function ( extensions, i ) {
var n = extensions.length;
View
@@ -4,49 +4,6 @@ var _ = window.rocketnia.lathe, $ = window.rocketnia.chops;
var choppaScript = window.rocketnia.choppascript;
-
-// ===== Demonstrations. =============================================
-
-var fact = _.rulebook( "fact" );
-
-_.rule( fact, "positive", function ( n ) {
- if ( n <= 0 ) return _.fail( "The number wasn't positive." );
- return _.win( n * fact( n - 1 ) );
-} );
-
-_.rule( fact, "zero", function ( n ) {
- if ( n != 0 ) return _.fail( "The number wasn't 0." );
- return _.win( 1 );
-} );
-
-_.rule( fact, "wrong zero", function ( n ) {
- if ( n != 0 ) return _.fail( "The number wasn't 0." );
- return _.win( 166 );
-} );
-
-// At the moment (although it's an unspecified behavior), the rule
-// sorts "zero" before "wrong zero" by default, so these will change
-// that.
-//
-//_.preferNamesFirst( "wrong zero is right", fact, "wrong zero" );
-//_.preferNamesLast( "right zero is wrong", fact, "zero" );
-_.preferNames( "wrong zero is more correct than right zero",
- fact, "wrong zero", "zero" );
-
-// These would have an effect if the rule system sorted things
-// differently by default.
-//
-//_.preferNamesFirst( "right zero is right", fact, "zero" );
-//_.preferNamesLast( "wrong zero is wrong", fact, "wrong zero" );
-//_.preferNames( "right zero is more correct than wrong zero",
-// _.fact, "zero", "wrong zero" );
-
-// TODO: See if normallyOrder() can be changed to make the order
-// last-defined-first-tried by default.
-
-_.orderRulebooks();
-
-
_.appendDom( window, { "load": function () {
_.blahrepl( _.el( "repl" ) );
@@ -62,17 +19,8 @@ _.appendDom( window, { "load": function () {
}
writeTest( "heya" );
- //var p = new _.Param( 1 );
- //var q = new _.Param( 2 );
- //writeTest( "hmm " + _.letParams( p, 3, q, 4, function () { return p.getValue() + " " + q.getValue(); } ) );
- //writeTest( "hmm " + _.isSecretargAware( _.secretargAware( function () { return 2; } ) ) );
- //writeTest( "hmm " + _.isSecretargAware( function () { return 2; } ) );
writeEl( _.dom( "br" ) );
- //writeTest( "hmm " + _.failfn( function ( a, b ) { return _.win( a + b ); } ).call( null, 1, 2 ) );
- //try {
- //writeTest( "hmm " + _.secretargAware( function () { return 2; } ).call() );
- //} catch ( e ) { alert( e ); }
var doOrDoNot = false;
@@ -85,12 +33,7 @@ _.appendDom( window, { "load": function () {
kindatry( function () {
- writeTest( "heya " + fact( 0 ) );
- writeTest( "beya " + fact( 4 ) );
-
- writeTest( "beya " + _.toArray( [ [ 1, 2, 3 ], [ 4, 5, 6 ] ] ) );
- writeTest( "beya " + _.asSeq( [ [ 1, 2, 3 ], [ 4, 5, 6 ] ], _.idfn ) );
- writeTest( "beya " + _.mappend( [], [ [ 1, 2, 3 ], [ 4, 5, 6 ] ], _.idfn ).length );
+ writeTest( "beya " + _.arrMappend( [ [ 1, 2, 3 ], [ 4, 5, 6 ] ], _.idfn ).length );
writeTest( "seya" );
writeTest( "seya " + _.blahpp( " woo hoo ".split( /\s+/ ) ) );
Oops, something went wrong.

0 comments on commit 6e3fa0f

Please sign in to comment.