Last active
December 12, 2016 01:31
-
-
Save kylejlin/511e9fd44e3861d9ec6e2888eca38a3d to your computer and use it in GitHub Desktop.
Dev TODO: Everything.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(qsc) { | |
var StateCodes = { | |
EXEC: 0, // Main execution state | |
WORD: 1, // /[a-zA-Z\$_][a-zA-Z0-9\$_]*/ | |
NUMBER: 2, // A sequence of digits, optionally preceded by 0x 0b or 0o | |
SPACE_TAB: 3, // Space or tab | |
PUNC_SEQ: 4, // A sequence of punctuation excluding (){}[] | |
LP: 5, // Left paren ( | |
RP: 6, // Right paren ) | |
LS: 7, // Left square bracket [ | |
RS: 8, // Right square bracket ] | |
LC: 9, // Left curly brace { | |
RC: 10, // Right curly brace } | |
INVALID: 11, | |
NEWLINE: 12, | |
COMMENT: 13, | |
STRING: 14, | |
STRING_PART: 15, | |
STRING_BACKSLASH: 16, | |
STRING_INTERPOLATION: 17 | |
}; | |
var EasyRe = { | |
ALPHA: /[a-zA-Z]/, | |
ALPHA_DOLLAR_UNDER: /[a-zA-Z\$_]/, | |
NUM: /\d/, | |
NUM_BIN: /[01]/, | |
NUM_OCT: /[0-7]/, | |
NUM_HEX: /[0-9a-fA-F]/, | |
ALPHA_DOLLAR_UNDER_NUM: /[a-zA-Z0-9\$_]/, | |
RAD_PRE_LETTER: /[xbo]/, // Radix prefix letter (x, b, or o, for 0x (hex), 0b (binary), or 0o (octal)) | |
WS: /\w/, | |
ST: / |\t/, // Space or tab | |
PUNC: /[\\\/\$\{\}\[\]\.\,\-\+\?\=\(\)\^\*\|~`!@#%&_:;'"<>]/, | |
DELIM: /\{\}\[\]\(\)/ | |
}; | |
function tokenize(code) { | |
var data = [{state: StateCodes.EXEC}]; | |
var tokens = []; | |
// TODOS: fill out endState stub | |
function getLatestData() { | |
return data[data.length - 1]; | |
} | |
function addState(state) { | |
data.push(state); | |
} | |
function redoCharCheck() { | |
i--; | |
} | |
function endState(options) { | |
var latestData = getLatestData(); | |
data.pop(); | |
options = options || {shouldNotAppend: false} | |
if (!options.shouldNotAppend) { | |
if (false) { | |
// Special case logic here | |
} else { | |
tokens.push(latestData); | |
} | |
} | |
} | |
for (var i = 0; i < code.length; i++) { | |
var char = code.charAt(i); | |
switch (getLatestData().state) { | |
case StateCodes.EXEC: | |
if (EasyRe.ALPHA_DOLLAR_UNDER.test(char)) { | |
addState({state: StateCodes.WORD, contents: char}); | |
} else if (EasyRe.NUM.test(char)) { | |
addState({state: StateCodes.NUMBER, contents: char, radix: 10}); | |
} else if (EasyRe.ST.test(char)) { | |
addState({state: StateCodes.SPACE_TAB}); | |
endState(); | |
} else if ('\n' === char) { | |
addState({state: StateCodes.NEWLINE}); | |
} else if (EasyRe.DELIM.test(char)) { | |
if (getLatestState().isStringInterpolation && '}' === char) { | |
endState(); | |
} else { | |
var delimState = ({ | |
'(': StateCodes.LP, | |
')': StateCodes.RP, | |
'[': StateCodes.LS, | |
']': StateCodes.RS, | |
'{': StateCodes.LB, | |
'}': StateCodes.RB | |
})[char]; | |
addState({state: delimState}); | |
endState(); | |
} else if (EasyRe.PUNC.test()) { | |
addState({state: StateCodes.PUNC_SEQ, contents: char}); | |
} | |
} | |
break; | |
case StateCodes.WORD: | |
if (EasyRe.ALPHA_DOLLAR_UNDER_NUM.test(char)) { | |
getLatestData().contents += char; | |
} else { | |
endState(); | |
redoCharCheck(); | |
} | |
break; | |
case StateCodes.NUMBER: | |
if (({2: EasyRe.NUM_BIN, 8: EasyRe.NUM_OCT, 10: EasyRe.NUM, 16: EasyRe.NUM_HEX})[getLatestData().radix].test(char)) { | |
getLatestData().contents += char; | |
} else if (this.contents.length === 1 && EasyRe.RAD_PRE_LETTER.test(char)) { | |
var radix = ({ | |
x: 16, | |
o: 8, | |
b: 2 | |
})[char]; | |
getLatestData().radix = radix; | |
} else if ('_' === char) { | |
// Do nothing. Underscores are allowed for readability. | |
} else { | |
addState({state: StateCodes.INVALID, char: char}); | |
endState(); | |
endState(); | |
} | |
break; | |
case StateCodes.SPACE_TAB: | |
break; | |
case StateCodes.PUNC_SEQ: | |
if ('//' === getLatestData().contents) { | |
endState({shouldNotAppend: true}); | |
addState({state: StateCodes.COMMENT, type: 'SL' /* SL for 'Single line' */, contents: ''}); | |
redoCharCheck(); | |
} else if ('/*' === getLatestData().contents) { | |
endState({shouldNotAppend: true}); | |
addState({state: StateCodes.COMMENT, type: 'ML' /* ML for 'Multi-line' */, contents: ''}); | |
redoCharCheck(); | |
} else if (!EasyRe.DELIM.test(char) && EasyRe.PUNC.test(char)) { | |
getLatestData().contents += char; | |
} else { | |
endState(); | |
redoCharCheck(); | |
} | |
break; | |
case StateCodes.INVALID: | |
break; | |
case StateCodes.NEWLINE: | |
break; | |
case StateCodes.STRING_BACKSLASH: | |
break; | |
case StateCodes.COMMENT: | |
if ('SL' === getLatestData().type) { | |
if ('\n' === char) { | |
endState(); | |
} else { | |
getLatestData().contents += char; | |
} | |
} else if ('ML' === getLatestData().type) { | |
getLatestData().contents += char; | |
if (getLatestData().contents.slice(-2) === '*/') { | |
getLatestData().contents = getLatestData().contents.slice(0, -2); | |
endState(); | |
} | |
} else { | |
// TODO: Error! | |
} | |
break; | |
case StateCodes.STRING: | |
if ('\\' === char) { | |
addToken({state: StateCodes.STRING_PART, contents: getLatestData().contents}); | |
getLatestData().contents = ''; | |
addState({state: EasyRe.STRING_BACKSLASH, escaped: ''}); | |
} else if ('${' === getLatestData().contents.slice(-2)) { | |
addToken({state: StateCodes.STRING_PART, contents: getLatestData().contents.slice(0, -2)}); | |
getLatestData.contents = ''; | |
addState({state: StateCodes.EXEC, stringInterpolation: true}); | |
} else { | |
getLatestData().contents += char; | |
if ('QUOTE' === getLatestData().delimType) { | |
if (("'" === getLatestData().slice(-1) && 'SINGLE' === getLatestData().quoteType) || | |
('"' === getLatestData().slice(-1) && 'DOUBLE' === getLatestData().quoteType)) { | |
getLatestData().contents = getLatestData().contents.slice(0, -1); | |
endState(); | |
} | |
} else if ('QUOTE_BRACE' === getLatestData().delimType) { | |
if (("'{" === getLatestData().slice(-2) && 'SINGLE' === getLatestData().quoteType) || | |
('"{' === getLatestData().slice(-2) && 'DOUBLE' === getLatestData().quoteType)) { | |
getLatestData().contents = getLatestData().contents.slice(0, -2); | |
endState(); | |
} | |
} else { | |
// TODO: Error! | |
} | |
} | |
break; | |
} | |
} | |
return tokens; | |
}; | |
/** START EXPORTS **/ | |
qsc.compiler.tokenize = tokenize; | |
})(QuartzscriptCompiler); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment