Permalink
Browse files

closes #66; implemented `<?` and `>?`

  • Loading branch information...
1 parent c011941 commit 6bbde55ef5a7772a9e6edf7edd3c3cdc143fe0ec @satyr committed Jun 15, 2011
Showing with 60 additions and 15 deletions.
  1. +11 −1 lib/ast.js
  2. +10 −6 lib/lexer.js
  3. +8 −1 src/ast.co
  4. +3 −2 src/lexer.co
  5. +28 −5 test/operator.co
View
@@ -1285,6 +1285,9 @@ exports.Op = Op = (function(_super){
break;
case '**':
return this.compilePow(o);
+ case '<?':
+ case '>?':
+ return this.compileMinMax(o);
case '&&':
case '||':
if (this['void'] || !o.level) {
@@ -1405,6 +1408,13 @@ exports.Op = Op = (function(_super){
return "(" + code + ")";
}
};
+ prototype.compileMinMax = function(o){
+ var lefts, rites, test;
+ lefts = this.first.cache(o, true);
+ rites = this.second.cache(o, true);
+ test = Op(this.op.charAt(0), lefts[0], rites[0]);
+ return If(test, lefts[1]).addElse(Block(rites[1])).compile(o);
+ };
prototype.compileMethod = function(o, klass, method, arg){
var args;
args = [this.second].concat(arg || []);
@@ -1542,7 +1552,7 @@ exports.Assign = Assign = (function(_super){
while (right instanceof Parens && !right.keep) {
right = right.it;
}
- if (op === '**=' || op === '+=' && right instanceof Arr || op === '*=' && right.isString() || (op === '-=' || op === '/=') && right.isMatcher()) {
+ if ((op === '<?=' || op === '>?=' || op === '**=') || op === '+=' && right instanceof Arr || op === '*=' && right.isString() || (op === '-=' || op === '/=') && right.isMatcher()) {
_ref = Chain(left).cacheReference(o), left = _ref[0], reft = _ref[1];
right = Op(op.slice(0, -1), reft, right);
op = ':=';
View
@@ -518,11 +518,6 @@ exports.doLiteral = function(code, index){
case '<<<<':
tag = 'IMPORT';
break;
- case '<<':
- case '>>':
- case '>>>':
- tag = 'SHIFT';
- break;
case '&':
case '|':
case '^':
@@ -541,6 +536,13 @@ exports.doLiteral = function(code, index){
case '!=':
tag = 'COMPARE';
break;
+ case '<<':
+ case '>>':
+ case '>>>':
+ case '<?':
+ case '>?':
+ tag = 'SHIFT';
+ break;
case '(':
case '?(':
this.closes.push(')');
@@ -588,6 +590,8 @@ exports.doLiteral = function(code, index){
case '<<=':
case '>>=':
case '>>>=':
+ case '<?=':
+ case '>?=':
case '**=':
tag = 'ASSIGN';
if (this.last[0] === 'LOGIC') {
@@ -873,7 +877,7 @@ COCO_ALIASES = {
};
RESERVED = ['var', 'const', 'enum', 'export', 'implements', 'interface', 'package', 'private', 'protected', 'public', 'static', 'yield'];
ID = /([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?![:=]))?|/g;
-SYMBOL = /[-+*\/%&|^:<>]=|\.{1,3}|([+&|:])\1|\([^\n\S]*\)|-[->]|[!=]==?|\?[.(]|~[.>]|<(?:<(?:=|<{0,2})|[-~])|>>>?=?|!\?|@@|\*\*=?|[^\s#]?/g;
+SYMBOL = /[-+*\/%&|^:<>]=|\.{1,3}|([+&|:])\1|\([^\n\S]*\)|-[->]|[!=]==?|\?[.(]|~[.>]|<(?:<(?:=|<{0,2})|[-~])|>>>?=?|[<>]\?=?|!\?|@@|\*\*=?|[^\s#]?/g;
SPACE = /(?=.)[^\n\S]*(?:#.*)?|/g;
MULTIDENT = /(?:\s*#.*)*(?:\n([^\n\S]*))+/g;
SIMPLESTR = /'[^\\']*(?:\\[\s\S][^\\']*)*'|/g;
View
@@ -753,6 +753,7 @@ class exports.Op extends Node
case \- then return @compileRemove o if @second.isMatcher()
case \/ then return @compileSplit o if @second.isMatcher()
case \** then return @compilePow o
+ case \<? \>? then return @compileMinMax o
case \&& \|| then @second.void = true if @void or not o.level
default
return @compileChain o if COMPARER.test @op and COMPARER.test @second.op
@@ -825,6 +826,12 @@ class exports.Op extends Node
code += ", #{ o.scope.free ref }"
if o.level < LEVEL_LIST then code else "(#{code})"
+ compileMinMax: (o) ->
+ lefts = @first .cache o, true
+ rites = @second.cache o, true
+ test = Op @op.charAt(0), lefts.0, rites.0
+ If test, lefts.1 .addElse Block rites.1 .compile o
+
compileMethod: (o, klass, method, arg) ->
args = [@second]concat arg || []
if @first"is#{klass}"()
@@ -902,7 +909,7 @@ class exports.Assign extends Node
left.=first
left.isAssignable() or left.carp 'invalid assign'
right.=it while right instanceof Parens and not right.keep
- if op is \**=
+ if op of <[ <?= >?= **= ]>
or op is \+= and right instanceof Arr
or op is \*= and right.isString()
or op of <[ -= /= ]> and right.isMatcher()
View
@@ -353,10 +353,10 @@ exports import
case \/ \% \** then tag = \MATH
case \++ \-- then tag = \CREMENT
case \<<< \<<<< then tag = \IMPORT
- case \<< \>> \>>> then tag = \SHIFT
case \& \| \^ then tag = \BITWISE
case \; then tag = \TERMINATOR
case <[ === !== < > <= >= == != ]> then tag = \COMPARE
+ case <[ << >> >>> <? >? ]> then tag = \SHIFT
case \( \?(
@closes.push \)
tag = \CALL( if val is \?( or @able true
@@ -372,7 +372,7 @@ exports import
@pair val
case \: then if @last.0 not of <[ ID STRNUM ) ]>
tag = \LABEL; val = ''
- case <[ = := += -= *= /= %= &= ^= |= <<= >>= >>>= **= ]>
+ case <[ = := += -= *= /= %= &= ^= |= <<= >>= >>>= <?= >?= **= ]>
tag = \ASSIGN
if @last.0 is \LOGIC
(val = new String val)logic = @tokens.pop()1
@@ -618,6 +618,7 @@ SYMBOL = //
| ~[.>] # bind access/function
| <(?: <(?:=|<{0,2}) | [-~]) # left shift / import / backcall
| >>>?=? # rite shift
+| [<>]\?=? # min/max
| !\? # inexistence
| @@ # `arguments`
| \*\*=? # pow
View
@@ -327,11 +327,34 @@ a[i++] **= 3
eq a.0, 8
-## Overloaded
+### Min/Max
+eq 0, 0 <? 0
+eq 1, 1 >? 1
+eq 2, 2 <? 3
+eq 3, 4 <? 3
+eq 4, 3 >? 4
+eq 5, 5 >? 4
+
+eq \a, \a <? \b
+eq \b, \a >? \b
+
+u = 42
+eq u, u*1 <? u+2 <? u*3
+eq u, u*1 >? u-2 >? u/3
+
+u <?= 9
+u >?= 0
+eq 9, u
+
+eq 99, u >?= 99
+eq 99, u
+
+
+### Overloaded
a = [0 1]
b = ''
-### Concat
+#### Concat
eq '0,1,2' String a + [2]
eq '3,4,5' String [3 4] + {0: 5, length: 1}
eq '0,1' ''+ b += [0 1]
@@ -342,20 +365,20 @@ y = [7 to 10]
[[] ...x, []] += y
eq '6,8,9' ''+ x
-### Join
+#### Join
eq '0==1' a * \==
eq '0101' [... a] * 2 * ''
eq '(01)' <[( )]> * "#{a * ''}"
eq '0@@1' (-> @@ * \@@) 0 1
eq '0.1' b *= \.
eq '0.1' b
-### Remove
+#### Remove
eq '01' b - \.
eq \. b -= /\d/g
eq '0.1' b = .1 - //#{2}//
-### Split
+#### Split
eq '0,1' String a / \,
eq 2 (/abc/ / /[^/]+/)length
eq "#{ x = ''+ Math.random() }"/'.'*'.' x

0 comments on commit 6bbde55

Please sign in to comment.