Skip to content

Commit

Permalink
unary ^ as cloning
Browse files Browse the repository at this point in the history
  • Loading branch information
satyr committed Aug 9, 2011
1 parent 1abb85e commit adc5f97
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 111 deletions.
2 changes: 2 additions & 0 deletions lib/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,8 @@ exports.Op = Op = (function(_super){
first.front = this.front;
}
break;
case '^':
return utility('clone') + "(" + first.compile(o, LEVEL_LIST) + ")";
case 'classof':
return utility('toString') + ".call(" + first.compile(o, LEVEL_LIST) + ").slice(8, -1)";
}
Expand Down
10 changes: 7 additions & 3 deletions lib/grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ bnf = {
return Op($1, $2);
}), o('SimpleAssignable CREMENT', function(){
return Op($2, $1, null, true);
}), o('Expression +- Expression', op = function(){
}), o('Expression +- Expression', op = function(){
return Op($2, $1, $3);
}), o('Expression COMPARE Expression', op), o('Expression LOGIC Expression', op), o('Expression MATH Expression', op), o('Expression SHIFT Expression', op), o('Expression BITWISE Expression', op), o('Expression RELATION Expression', function(){
}), o('Expression ^ Expression', op), o('Expression COMPARE Expression', op), o('Expression LOGIC Expression', op), o('Expression MATH Expression', op), o('Expression SHIFT Expression', op), o('Expression BITWISE Expression', op), o('Expression RELATION Expression', function(){
return '!' === $2.charAt(0)
? Op($2.slice(1), $1, $3).invert()
: Op($2, $1, $3);
Expand All @@ -119,6 +119,10 @@ bnf = {
return Op($1, $2);
}, {
prec: 'UNARY'
}), o('^ Expression', function(){
return Op($1, $2);
}, {
prec: 'UNARY'
}), o('Chain !?', function(){
return Existence($1.unwrap(), true);
}), o('Function'), o('FUNCTION Function', function(){
Expand Down Expand Up @@ -333,7 +337,7 @@ bnf = {
})
]
};
operators = [['left', 'POST_IF', 'FOR', 'WHILE'], ['right', ',', 'ASSIGN', 'HURL', 'EXTENDS', 'INDENT', 'SWITCH', 'CASE', 'TO', 'BY'], ['right', 'LOGIC'], ['left', 'BITWISE'], ['right', 'COMPARE'], ['left', 'RELATION'], ['left', 'SHIFT', 'IMPORT'], ['left', '+-'], ['left', 'MATH'], ['right', 'UNARY'], ['nonassoc', 'CREMENT']];
operators = [['left', 'POST_IF', 'FOR', 'WHILE'], ['right', ',', 'ASSIGN', 'HURL', 'EXTENDS', 'INDENT', 'SWITCH', 'CASE', 'TO', 'BY'], ['right', 'LOGIC'], ['left', '^', 'BITWISE'], ['right', 'COMPARE'], ['left', 'RELATION'], ['left', 'SHIFT', 'IMPORT'], ['left', '+-'], ['left', 'MATH'], ['right', 'UNARY'], ['nonassoc', 'CREMENT']];
tokens = (function(){
var _ref, _i, _ref2, _len, _j, _ref3, _len2, _results = [];
for (name in _ref = bnf) {
Expand Down
6 changes: 3 additions & 3 deletions lib/lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ var rewrite, able, string, TABS, INDENTS, LINES, BACKSLASHES, reslash, KEYWORDS_
};
_ref = require('./rewriter'), rewrite = _ref.rewrite, able = _ref.able;
exports.lex = function(code, options){
return __clone(exports).tokenize(code || '', options || {});
return (__clone(exports)).tokenize(code || '', options || {});
};
exports.tokenize = function(code, o){
var i, c, that;
Expand Down Expand Up @@ -260,6 +260,7 @@ exports.doNumber = function(code, lastIndex){
if (isNaN(num) || num === parseInt(rnum.slice(0, -1), radix)) {
this.carp("invalid number " + rnum + " in base " + radix);
}
num += '';
}
if (!last.spaced) {
if (sign = last[0] === '+-') {
Expand Down Expand Up @@ -518,7 +519,6 @@ exports.doLiteral = function(code, index){
break;
case '&':
case '|':
case '^':
tag = 'BITWISE';
break;
case ';':
Expand Down Expand Up @@ -901,4 +901,4 @@ NUMBER_OMIT = /_+/g;
REGEX = /\/([^[\/\n\\]*(?:(?:\\.|\[[^\]\n\\]*(?:\\.[^\]\n\\]*)*\])[^[\/\n\\]*)*)\/([gimy]{1,4}|\$?)|/g;
HEREGEX_OMIT = /\s+(?:#.*)?/g;
LASTDENT = /\n[^\n\S]*$/;
LINE_CONTINUER = /^\s*(?:[,&|^>%]|\.(?![.\d])|<(?![-~[])|!?\?|(?:and|or)(?![$\w\x7f-\uffff]|[^\n\S]*:(?![:=])))/;
LINE_CONTINUER = /^\s*(?:[,&|>%]|\.(?![.\d])|<(?![-~[])|!?\?|(?:and|or)(?![$\w\x7f-\uffff]|[^\n\S]*:(?![:=])))/;
158 changes: 80 additions & 78 deletions lib/parser.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions lib/rewriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ function addImplicitParentheses(tokens){
}
continue;
}
if (!(__indexOf.call(ARG, tag) >= 0 || tag === '+-' && !token.spaced)) {
if (!(__indexOf.call(ARG, tag) >= 0 || !token.spaced && (tag === '+-' || tag === '^'))) {
continue;
}
if (postfn && (tag === 'PARAM(' || tag === '->')) {
Expand Down Expand Up @@ -330,13 +330,13 @@ function addImplicitParentheses(tokens){
}
}
function expandLiterals(tokens){
var i, token, num, sig, ts, lno, to, n, that, _step, _ref;
var i, token, sig, ts, lno, to, n, that, _step, _ref;
i = -1;
while (token = tokens[++i]) {
switch (token[0]) {
case 'STRNUM':
if (~'-+'.indexOf(sig = (num = '' + token[1]).charAt(0))) {
token[1] = num.slice(1);
if (~'-+'.indexOf(sig = token[1].charAt(0))) {
token[1] = token[1].slice(1);
tokens.splice(i++, 0, ['+-', sig, token[2]]);
}
if (token.callable) {
Expand All @@ -346,7 +346,7 @@ function expandLiterals(tokens){
case 'RANGE':
ts = [];
lno = token[2];
to = token.to - (token.op === 'to' ? 0 : 1e-15);
to = token.to - (token.op === 'til' && 1e-15);
for (n = +token[1], _step = +token.by || 1; _step < 0 ? n >= to : n <= to; n += _step) {
if (2048 < ts.push(['STRNUM', n, lno], [',', ',', lno])) {
carp('range limit exceeded', lno);
Expand Down
8 changes: 5 additions & 3 deletions src/ast.co
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ exports.parse = (json) -> exports.fromJSON JSON.parse json
exports.fromJSON = function
return it unless it and typeof it is \object
if it.type
node = exports[that]::{}
node = ^exports[that]::
node[key] = fromJSON val for key, val in it
return node
if it.length? then fromJSON v for v of it else it
Expand Down Expand Up @@ -806,6 +806,8 @@ class exports.Op extends Node
if first instanceof Var and not o.scope.check first.value, true
@carp "#{ crement op } of undeclared variable \"#{first.value}\""
first{front} = this if @post
case \^
return "#{ utility \clone }(#{ first.compile o, LEVEL_LIST })"
case \classof
return "#{ utility \toString }.call(
#{ first.compile o, LEVEL_LIST }).slice(8, -1)"
Expand Down Expand Up @@ -863,7 +865,7 @@ class exports.Op extends Node
return x.compile o if 1 <= n < 2
# `[x] * 2` => `[x, x]`
if items
if n < 1 then return Block::{lines: items}add(JS '[]')compile o
if n < 1 then return (^Block::<<< lines: items)add(JS '[]')compile o
refs = []
[items[i], refs.*] = item.cache o, 1x for item, i of items
items.push JS() <<<
Expand Down Expand Up @@ -1069,7 +1071,7 @@ class exports.Assign extends Node
return tail if tail.isEmpty()
if tail instanceof Obj
then Clone head, tail.items
else Chain head, [Index::{key: tail.items || tail.maybeKey()}]
else Chain head, [^Index::<<< key: tail.items || tail.maybeKey()]

#### Import
# Copies properties from right to left.
Expand Down
3 changes: 2 additions & 1 deletion src/command.co
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ function repl
vm = require \vm
context = vm.createContext()
context <<< {...global, module, require, global: context}
repl.completer = require(\repl)REPLServer::{context, commands: []}~complete
repl.completer =
(^require(\repl)REPLServer::<<<{context, commands: []})~complete
repl._ttyWrite = (char) -> cont := char is \\n; @[]_ttyWrite ...
repl.on \attemptClose ->
if repl.line or code then say ''; reset() else repl.close()
Expand Down
16 changes: 9 additions & 7 deletions src/grammar.co
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,13 @@ bnf =
# a single generic "Operand OpSymbol Operand"-type rule,
# but in order to make the precedence binding possible, separate
# rules are necessary.
o 'Expression +- Expression' op = -> Op $2, $1, $3
o 'Expression COMPARE Expression' op
o 'Expression LOGIC Expression' op
o 'Expression MATH Expression' op
o 'Expression SHIFT Expression' op
o 'Expression BITWISE Expression' op
o 'Expression +- Expression' op = -> Op $2, $1, $3
o 'Expression ^ Expression' op
o 'Expression COMPARE Expression' op
o 'Expression LOGIC Expression' op
o 'Expression MATH Expression' op
o 'Expression SHIFT Expression' op
o 'Expression BITWISE Expression' op

o 'Expression RELATION Expression' ->
[]= if \! is $2.charAt 0
Expand All @@ -156,6 +157,7 @@ bnf =

o 'UNARY Expression' -> []= if $1 is \! then $2.invert() else Op $1, $2
o '+- Expression' (-> Op $1, $2), prec: \UNARY
o '^ Expression' (-> Op $1, $2), prec: \UNARY

o 'Chain !?' -> Existence $1.unwrap(), true

Expand Down Expand Up @@ -312,7 +314,7 @@ operators =
<[ left POST_IF FOR WHILE ]>
<[ right , ASSIGN HURL EXTENDS INDENT SWITCH CASE TO BY ]>
<[ right LOGIC ]>
<[ left BITWISE ]>
<[ left ^ BITWISE ]>
<[ right COMPARE ]>
<[ left RELATION ]>
<[ left SHIFT IMPORT ]>
Expand Down
9 changes: 5 additions & 4 deletions src/lexer.co
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ exports import
# remaining code, or a custom recursive token-matching method
# (for interpolations). When the next token has been recorded,
# we move forward within the code past the token, and begin again.
) -> exports{}tokenize code||'' options||{}
) -> (^exports)tokenize code||'' options||{}
tokenize: (code, o) ->
@inter or code.=replace /\r/g ''
# Prepend a newline to handle leading INDENT.
Expand Down Expand Up @@ -173,6 +173,7 @@ exports import
num = parseInt rnum = match.2.replace(NUMBER_OMIT, ''), radix
if isNaN num or num is parseInt rnum.slice(0 -1), radix
@carp "invalid number #rnum in base #radix"
num += ''
unless last.spaced
if sign = last.0 is \+-
num = last.1 + num
Expand Down Expand Up @@ -352,7 +353,7 @@ exports import
case \/ \% \** then tag = \MATH
case \++ \-- then tag = \CREMENT
case \<<< \<<<< then tag = \IMPORT
case \& \| \^ then tag = \BITWISE
case \& \| then tag = \BITWISE
case \; then tag = \TERMINATOR
case <[ === !== < > <= >= == != ]> then tag = \COMPARE
case <[ << >> >>> <? >? ]> then tag = \SHIFT
Expand Down Expand Up @@ -465,7 +466,7 @@ exports import
str.=slice delta = i + 1 + id.length
parts.push [\TOKENS nested = [[\ID id, @line]]]
else
clone = exports{+inter, @emender}
clone = ^exports <<< {+inter, @emender}
nested = clone.tokenize str.slice(i+2), {@line, +raw}
nested.shift() while nested.0?0 is \TERMINATOR
@countLines str.slice i, delta = str.length - clone.rest.length
Expand Down Expand Up @@ -663,6 +664,6 @@ HEREGEX_OMIT = /\s+(?:#.*)?/g
LASTDENT = /\n[^\n\S]*$/

LINE_CONTINUER = // ^ \s* (?
: [,&|^>%] | \.(?![.\d]) | <(?![-~[]) | !?\?
: [,&|>%] | \.(?![.\d]) | <(?![-~[]) | !?\?
| (?:and|or)(?![$\w\x7f-\uffff]|[^\n\S]*:(?![:=]))
) //
9 changes: 4 additions & 5 deletions src/rewriter.co
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ function addImplicitParentheses tokens
tokens.splice i-1 1
token.1 = \?(
continue
continue unless tag of ARG or tag is \+- and not token.spaced
continue unless tag of ARG or not token.spaced and tag of <[ +- ^ ]>
continue if postfn and tag of <[ PARAM( -> ]>
if tag is \CREMENT
continue if token.spaced or tokens[i+1]?0 not of CHAIN
Expand Down Expand Up @@ -220,13 +220,12 @@ function expandLiterals tokens
while token = tokens[++i]
switch token.0
case \STRNUM
if ~'-+'indexOf sig = (num = '' + token.1)charAt 0
token.1 = num.slice 1
if ~'-+'indexOf sig = token.1.charAt 0
token.1.=slice 1
tokens.splice i++ 0 [\+- sig, token.2]
continue if token.callable
case \RANGE
ts = []; lno = token.2
to = token.to - if token.op is \to then 0 else 1e-15
ts = []; lno = token.2; to = token.to - (token.op is \til and 1e-15)
for n from +token.1 to to by +token.by or 1
if 32r200 < ts.push [\STRNUM n, lno] [\, \, lno]
carp 'range limit exceeded' lno
Expand Down
3 changes: 1 addition & 2 deletions test/operator.co
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ and null
!? true
and : 'property name'
andy!? # nickname
eq 7 1
eq 3 1
& 2
| 3
^ 4
else ok 0 'leading logical/bitwise operators should continue lines'


Expand Down

0 comments on commit adc5f97

Please sign in to comment.