diff --git a/resources/evaluate.q b/resources/evaluate.q index d22b223d..f6088a87 100644 --- a/resources/evaluate.q +++ b/resources/evaluate.q @@ -1,137 +1,206 @@ -{[ctx; code; stringify] - if [-10h ~ type ctx; - ctx: enlist ctx]; - toString: {[data] - text : .Q.s data; - : $[all text in " \r\n"; - .Q.s1[data] , "\n"; - text]; - }; - removeMultilineComments: {[text] - text: "\n" , text; - lines: (where text = "\n") cut text; - potentialStart: where lines like "\n/*"; - start: potentialStart where all each (2_/:lines potentialStart) in "\t "; - potentialEnd: where lines like "\n\\*"; - end: 1 + potentialEnd where all each (2_/:lines potentialEnd) in "\t "; - lines[0]: 1 _ lines[0]; - boundaries: (`start,' start), (`end,' end); - boundaries: boundaries iasc boundaries[;1]; - if [`end ~ first first boundaries; - : "\n" sv (boundaries[0;1] - 1) # lines]; - filteredList: (); - lastBoundary: `end; - index: 0; - do [count boundaries; - if [lastBoundary <> first boundaries index; - lastBoundary: first boundaries index; - filteredList,: enlist boundaries index]; - index+: 1]; - result: raze first each 2 cut raze each (0, filteredList[;1]) cut lines; - : $[result ~ (); - ""; - result]; - }; - tokenize: {[text] - parsed: -4!text; - cmtInd: where ((1 < count each parsed) & parsed[;0] in "/ \t\n") & not parsed ~\: "/:"; - parsed[cmtInd] : (parsed[cmtInd]?\:"/")#'parsed[cmtInd]; - parsed where (0 <> count each parsed) - }; - stripTrailingSemi: {[tokenize; str] - str: tokenize str; - $[ ("" ~ str) or (() ~ str); - ""; - {(neg sum &\[reverse x in "\r\n; \t"]) _ x} trim raze str] - } tokenize; - splitExpression: {[expr] - tokens: -4!expr; - newlines: where enlist["\n"] ~/: tokens; - : "c"$raze each (0 , 1 + newlines where not tokens[1 + newlines] in enlist each " \t\r\n") _ tokens - }; - fixSpecialSyntax: {[stripTrailingSemi; expr] - escape: {[str] - chars: (`char$til 255)!(string each `char$til 255); - chars[("\\";"\"";"\t";"\n";"\r")]: ("\\\\";"\\\"";"\\t";"\\n";"\\r"); - : raze chars str; - }; - $[ - expr like "[kq])*"; - "value \"",(2#expr), escape[stripTrailingSemi 2_expr], "\";"; - expr like "\\*"; - "system \"", escape[trim 1_expr], "\";"; - {s:rtrim first l:(0,x ss "::")_x; (1 first boundaries index; + lastBoundary: first boundaries index; + filteredList,: enlist boundaries index]; + index+: 1]; + result: raze first each 2 cut raze each (0, filteredList[;1]) cut lines; + : $[result ~ (); + ""; + result]; + }; + tokenize: {[text] + parsed: -4!text; + cmtInd: where ((1 < count each parsed) & parsed[;0] in "/ \t\n") & not parsed ~\: "/:"; + parsed[cmtInd] : (parsed[cmtInd]?\:"/")#'parsed[cmtInd]; + parsed where (0 <> count each parsed) + }; + stripTrailingSemi: {[tokenize; str] + str: tokenize str; + $[ ("" ~ str) or (() ~ str); + ""; + {(neg sum &\[reverse x in "\r\n; \t"]) _ x} trim raze str] + } tokenize; + splitExpression: {[expr] + tokens: -4!expr; + newlines: where enlist["\n"] ~/: tokens; + : "c"$raze each (0 , 1 + newlines where not tokens[1 + newlines] in enlist each " \t\r\n") _ tokens + }; + fixSpecialSyntax: {[stripTrailingSemi; expr] + escape: {[str] + chars: (`char$til 255)!(string each `char$til 255); + chars[("\\";"\"";"\t";"\n";"\r")]: ("\\\\";"\\\"";"\\t";"\\n";"\\r"); + : raze chars str; + }; + $[ + expr like "[kq])*"; + "value \"",(2#expr), escape[stripTrailingSemi 2_expr], "\";"; + expr like "\\*"; + "system \"", escape[trim 1_expr], "\";"; + {s:rtrim first l:(0,x ss "::")_x; (1 `; returnDictionary[`attributes]: attr data]; + :returnDictionary + }[removeTrailingNewline;toString]; + generateTableColumns:{[generateColumns; originalType; isAtom; isKey; data] + if [.Q.qp data; + ' "Partitioned tables cannot be displayed in this view"]; + if [0b ~ .Q.qp data; + ' "This view is not supported for splayed tables"]; + generateColumns[originalType; isAtom; isKey] ./: flip (value; key) @\: flip data + }[generateColumns]; + toStructuredText:{[generateTableColumns; generateColumns; data; quantity; isAtom; originalType] + if[(type data) ~ 10h; data: enlist data]; + isTable: .Q.qt data; + isDict: 99h ~ type data; + columns: $[ + isTable and isDict; + raze (generateTableColumns[::;0b;1b;key data]; generateTableColumns[::;0b;0b;value data]); + isDict; + (generateColumns[::;0b;1b;key data;"key"]; generateColumns[::;0b;0b;value data;"values"]); + isTable; + generateTableColumns[originalType;isAtom;0b;data]; + ]; + : .j.j `count`columns!(quantity; columns) + }[generateTableColumns; generateColumns]; + typeOf: {$[0>type x; .axq.i_PRIMCODE neg type x; .axq.i_NONPRIMCODE type x]}; + isAtom: {not type[x] within 0 99h}; + sample: {[sampleFn; sampleSize; data] + sampleSize: min (sampleSize; count data); + fn: $[ sampleFn ~ "random"; + {[sampleSize; data] + $[ type[data] ~ 99h; + [ ii: neg[sampleSize]?count data; + (key[data] ii)!value[data]ii]; + neg[sampleSize]?data] + }; + sampleFn ~ "first"; #; + sampleFn ~ "last"; {neg[x]#y}; + ' "Unrecognized sample function"]; + fn[sampleSize; data] + } + result: evalInContext[ctx; splitExpression stripTrailingSemi wrapLines removeMultilineComments code]; + if[result `errored; :result]; + if[type[result[`result]] = 99h; + if[`output in key result[`result]; + if[type[result[`result][`output]] = 99h; + if[`bytes in key result[`result][`output]; + result[`base64]:1b; result[`result]: .Q.btoa result[`result][`output][`bytes]; :result]]]]; + if [returnFormat ~ "text"; + result[`result]: toString result `result]; + if [returnFormat ~ "structuredText"; + result[`result]: toStructuredText[result `result;count result`result; isAtom result`result; typeOf result`result]]; + result + }