
sweetjs-0.2.5.node_modules.sweet.js.src.syntax.js Maven / Gradle / Ivy
The newest version!
(function (root, factory) {
if (typeof exports === 'object') {
// CommonJS
factory(exports, require('underscore'), require("es6-collections"), require("./parser"));
} else if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['exports', 'underscore', 'es6-collections', 'parser'], factory);
}
}(this, function(exports, _, es6, parser) {
// (CSyntax, Str) -> CContext
function Rename(id, name, ctx, defctx) {
defctx = defctx || null;
return {
id: id,
name: name,
context: ctx,
def: defctx
};
}
// (Num) -> CContext
function Mark(mark, ctx) {
return {
mark: mark,
context: ctx
};
}
function Def(defctx, ctx) {
return {
defctx: defctx,
context: ctx
};
}
function Var(id) {
return {
id: id
};
}
var isRename = function(r) {
return r && (typeof r.id !== 'undefined') && (typeof r.name !== 'undefined');
};
var isMark = function isMark(m) {
return m && (typeof m.mark !== 'undefined');
};
function isDef(ctx) {
return ctx && (typeof ctx.defctx !== 'undefined');
}
// (CToken, CSyntax?) -> CSyntax
function syntaxFromToken(token, oldstx) {
return Object.create({
// (Int) -> CSyntax
// non mutating
mark: function mark(newMark) {
if (this.token.inner) {
var next = syntaxFromToken(this.token, this);
next.deferredContext = Mark(newMark, this.deferredContext);
return next;
}
return syntaxFromToken(this.token, {context: Mark(newMark, this.context)});
},
// (CSyntax or [...CSyntax], Str) -> CSyntax
// non mutating
rename: function(id, name) {
// deferr renaming of delimiters
if (this.token.inner) {
var next = syntaxFromToken(this.token, this);
next.deferredContext = Rename(id, name, this.deferredContext);
return next;
}
if (this.token.type === parser.Token.Identifier ||
this.token.type === parser.Token.Keyword) {
return syntaxFromToken(this.token, {context: Rename(id, name, this.context)});
} else {
return this;
}
},
addDefCtx: function(defctx) {
if (this.token.inner) {
var next = syntaxFromToken(this.token, this);
next.deferredContext = Def(defctx, this.deferredContext);
return next;
}
return syntaxFromToken(this.token, {context: Def(defctx, this.context)});
},
getDefCtx: function() {
var ctx = this.context;
while(ctx !== null) {
if (isDef(ctx)) {
return ctx.defctx;
}
ctx = ctx.context;
}
return null;
},
expose: function() {
parser.assert(this.token.type === parser.Token.Delimiter,
"Only delimiters can be exposed");
function applyContext(stxCtx, ctx) {
if (ctx == null) {
return stxCtx;
} else if (isRename(ctx)) {
return Rename(ctx.id, ctx.name, applyContext(stxCtx, ctx.context))
} else if (isMark(ctx)) {
return Mark(ctx.mark, applyContext(stxCtx, ctx.context));
} else if (isDef(ctx)) {
return Def(ctx.defctx, applyContext(stxCtx, ctx.context));
} else {
parser.assert(false, "unknown context type");
}
}
this.token.inner = _.map(this.token.inner, _.bind(function(stx) {
if (stx.token.inner) {
var next = syntaxFromToken(stx.token, stx);
next.deferredContext = applyContext(stx.deferredContext, this.deferredContext);
return next;
} else {
return syntaxFromToken(stx.token,
{context: applyContext(stx.context, this.deferredContext)});
}
}, this));
this.deferredContext = null;
return this;
},
toString: function() {
var val = this.token.type === parser.Token.EOF ? "EOF" : this.token.value;
return "[Syntax: " + val + "]";
}
}, {
token: { value: token, enumerable: true, configurable: true},
context: {
// if given old syntax object steal its context otherwise create one fresh
value: (oldstx && oldstx.context) ? oldstx.context : null,
writable: true, enumerable: true, configurable: true
},
deferredContext: {
value: (oldstx && oldstx.deferredContext) ? oldstx.deferredContext : null,
writable: true, enumerable: true, configurable: true
}
});
}
function mkSyntax(stx, value, type, inner) {
if (stx && Array.isArray(stx) && stx.length === 1) {
stx = stx[0];
} else if (stx && Array.isArray(stx)) {
throw new Error("Expecting a syntax object or an array with a single syntax object, not: " + stx);
}
if (type === parser.Token.Delimiter) {
var startLineNumber, startLineStart, endLineNumber, endLineStart, startRange, endRange;
if (!Array.isArray(inner)) {
throw new Error("Must provide inner array of syntax objects when creating a delimiter");
}
if(stx && stx.token.type === parser.Token.Delimiter) {
startLineNumber = stx.token.startLineNumber;
startLineStart = stx.token.startLineStart
endLineNumber = stx.token.endLineNumber;
endLineStart = stx.token.endLineStart;
startRange = stx.token.startRange;
endRange = stx.token.endRange;
} else if (stx && stx.token){
startLineNumber = stx.token.lineNumber;
startLineStart = stx.token.lineStart;
endLineNumber = stx.token.lineNumber;
endLineStart = stx.token.lineStart;
startRange = stx.token.range;
endRange = stx.token.range
} else {
startLineNumber = 0;
startLineStart = 0;
endLineNumber = 0;
endLineStart = 0;
startRange = [0, 0];
endRange = [0, 0];
}
return syntaxFromToken({
type: parser.Token.Delimiter,
value: value,
inner: inner,
startLineStart: startLineStart,
startLineNumber: startLineNumber,
endLineStart: endLineStart,
endLineNumber: endLineNumber,
startRange: startRange,
endRange: endRange
}, stx);
} else {
var lineStart, lineNumber, range;
if (stx && stx.token.type === parser.Token.Delimiter) {
lineStart = stx.token.startLineStart;
lineNumber = stx.token.startLineNumber;
range = stx.token.startRange;
} else if(stx && stx.token) {
lineStart = stx.token.lineStart;
lineNumber = stx.token.lineNumber;
range = stx.token.range;
} else {
lineStart = 0;
lineNumber = 0;
range = [0, 0];
}
return syntaxFromToken({
type: type,
value: value,
lineStart: lineStart,
lineNumber: lineNumber,
range: range
}, stx);
}
}
function makeValue(val, stx) {
if(typeof val === 'boolean') {
return mkSyntax(stx, val ? "true" : "false", parser.Token.BooleanLiteral);
} else if (typeof val === 'number') {
if (val !== val) {
return makeDelim('()', [makeValue(0, stx), makePunc('/', stx), makeValue(0, stx)], stx);
} if (val < 0) {
return makeDelim('()', [makePunc('-', stx), makeValue(Math.abs(val), stx)], stx);
} else {
return mkSyntax(stx, val, parser.Token.NumericLiteral);
}
} else if (typeof val === 'string') {
return mkSyntax(stx, val, parser.Token.StringLiteral);
} else if (val === null) {
return mkSyntax(stx, 'null', parser.Token.NullLiteral);
} else {
throw new Error("Cannot make value syntax object from: " + val);
}
}
function makeRegex(val, flags, stx) {
var newstx = mkSyntax(stx, new RegExp(val, flags), parser.Token.RegexLiteral);
// regex tokens need the extra field literal on token
newstx.token.literal = val;
return newstx;
}
function makeIdent(val, stx) {
return mkSyntax(stx, val, parser.Token.Identifier);
}
function makeKeyword(val, stx) {
return mkSyntax(stx, val, parser.Token.Keyword);
}
function makePunc(val, stx) {
return mkSyntax(stx, val, parser.Token.Punctuator);
}
function makeDelim(val, inner, stx) {
return mkSyntax(stx, val, parser.Token.Delimiter, inner);
}
function unwrapSyntax(stx) {
if (Array.isArray(stx) && stx.length === 1) {
// pull stx out of single element arrays for convenience
stx = stx[0];
}
if (stx.token) {
if(stx.token.type === parser.Token.Delimiter) {
return stx.token;
} else {
return stx.token.value;
}
} else {
throw new Error ("Not a syntax object: " + stx);
}
}
// ([...CSyntax]) -> [...CToken]
function syntaxToTokens(stx) {
return _.map(stx, function(stx) {
if (stx.token.inner) {
stx.token.inner = syntaxToTokens(stx.token.inner);
}
return stx.token;
});
}
// (CToken or [...CToken]) -> [...CSyntax]
function tokensToSyntax(tokens) {
if (!_.isArray(tokens)) {
tokens = [tokens];
}
return _.map(tokens, function(token) {
if (token.inner) {
token.inner = tokensToSyntax(token.inner);
}
return syntaxFromToken(token);
});
}
// ([...CSyntax], Str) -> [...CSyntax])
function joinSyntax(tojoin, punc) {
if (tojoin.length === 0) { return []; }
if (punc === " ") { return tojoin; }
return _.reduce(_.rest(tojoin, 1), function (acc, join) {
return acc.concat(makePunc(punc, join), join);
}, [_.first(tojoin)]);
}
// ([...[...CSyntax]], Str) -> [...CSyntax]
function joinSyntaxArr(tojoin, punc) {
if (tojoin.length === 0) { return []; }
if (punc === " ") {
return _.flatten(tojoin, true);
}
return _.reduce(_.rest(tojoin, 1), function (acc, join){
return acc.concat(makePunc(punc, _.first(join)),
join);
}, _.first(tojoin));
}
exports.unwrapSyntax = unwrapSyntax;
exports.makeDelim = makeDelim;
exports.makePunc = makePunc;
exports.makeKeyword = makeKeyword;
exports.makeIdent = makeIdent;
exports.makeRegex = makeRegex;
exports.makeValue = makeValue;
exports.Rename = Rename;
exports.Mark = Mark;
exports.Var = Var;
exports.Def = Def;
exports.isDef = isDef;
exports.isMark = isMark;
exports.isRename = isRename;
exports.syntaxFromToken = syntaxFromToken;
exports.tokensToSyntax = tokensToSyntax;
exports.syntaxToTokens = syntaxToTokens;
exports.joinSyntax = joinSyntax;
exports.joinSyntaxArr = joinSyntaxArr;
}));
© 2015 - 2025 Weber Informatics LLC | Privacy Policy