diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..48f5292
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,29 @@
+Copyright 2009-2015 Jason Turner
+Copyright 2009-2012 Jonathan Turner.
+
+All Rights Reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Jason Turner nor Jonathan Turner nor the
+ name of contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/cheatsheet.md b/cheatsheet.md
index b8be1a9..fc229ac 100644
--- a/cheatsheet.md
+++ b/cheatsheet.md
@@ -258,4 +258,15 @@ print(get_value(m)); // prints "Value Is: a"
+# Built In Functions
+
+## Evaluation
+
+```
+eval("4 + 5") // dynamically eval script string and returns value of last statement
+eval_file("filename") // evals file and returns value of last statement
+use("filename") // evals file exactly once and returns value of last statement
+ // if the file had already been 'used' nothing happens and undefined is returned
+```
+
diff --git a/contrib/sublimetext/ChaiScript.YAML-tmLanguage b/contrib/sublimetext/ChaiScript.YAML-tmLanguage
new file mode 100644
index 0000000..7596d47
--- /dev/null
+++ b/contrib/sublimetext/ChaiScript.YAML-tmLanguage
@@ -0,0 +1,93 @@
+# [PackageDev] target_format: plist, ext: tmLanguage
+---
+comment: 'ChaiScript Syntax: version 2.0'
+fileTypes: [chai]
+firstLineMatch: ^#!/usr/bin/env node
+foldingStartMarker: ^.*\bdef\s*(\w+\s*)?\([^\)]*\)(\s*\{[^\}]*)?\s*$
+foldingStopMarker: ^\s*\}
+keyEquivalent: ^~J
+name: ChaiScript
+patterns:
+- {comment: chaiscript shebang, match: ^#, name: comment.line.chai}
+- {match: '\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?))\b', name: constant.numeric.chai}
+- begin: ''''
+ beginCaptures:
+ '0': {name: punctuation.definition.string.begin.chai}
+ end: ''''
+ endCaptures:
+ '0': {name: punctuation.definition.string.end.chai}
+ name: string.quoted.single.chai
+ patterns:
+ - {match: '\\(x\h{2}|[0-2][0-7]{,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)', name: constant.character.escape.chai}
+- begin: '"'
+ beginCaptures:
+ '0': {name: punctuation.definition.string.begin.chai}
+ end: '"'
+ endCaptures:
+ '0': {name: punctuation.definition.string.end.chai}
+ name: string.quoted.double.chai
+ patterns:
+ - {match: '\\(x\h{2}|[0-2][0-7]{,2}|3[0-6][0-7]|37[0-7]?|[4-7][0-7]?|.)', name: constant.character.escape.chai}
+- begin: /\*\*(?!/)
+ captures:
+ '0': {name: punctuation.definition.comment.chai}
+ end: \*/
+ name: comment.block.documentation.chai
+- begin: /\*
+ captures:
+ '0': {name: punctuation.definition.comment.chai}
+ end: \*/
+ name: comment.block.chai
+- captures:
+ '1': {name: punctuation.definition.comment.chai}
+ match: (//).*$\n?
+ name: comment.line.double-slash.chai
+- captures:
+ '0': {name: punctuation.definition.comment.html.chai}
+ '2': {name: punctuation.definition.comment.html.chai}
+ match: ()
+ name: comment.block.html.chai
+- {match: \b(boolean|byte|char|class|double|enum|float|fun|def|int|interface|long|short|var|auto|attr)\b,
+ name: storage.type.chai}
+- {match: \b(break|case|catch|continue|default|do|else|finally|else if|for|goto|if|return|switch|throw|try|while)\b,
+ name: keyword.control.chai}
+- {match: \b(delete|in|instanceof|new|typeof|with)\b, name: keyword.operator.chai}
+- {match: \btrue\b, name: constant.language.boolean.true.chai}
+- {match: \bfalse\b, name: constant.language.boolean.false.chai}
+- {match: \bnull\b, name: constant.language.null.chai}
+- {match: \b(Anchor|Applet|Area|Array|Boolean|Button|Checkbox|Date|document|event|FileUpload|Form|Frame|Function|Hidden|History|Image|JavaArray|JavaClass|JavaObject|JavaPackage|java|Layer|Link|Location|Math|MimeType|Number|navigator|netscape|Object|Option|Packages|Password|Plugin|Radio|RegExp|Reset|Select|String|Style|Submit|screen|sun|Text|Textarea|window|XMLHttpRequest)\b,
+ name: support.class.chai}
+- {match: '\b(s(h(ift|ow(Mod(elessDialog|alDialog)|Help))|croll(X|By(Pages|Lines)?|Y|To)?|t(op|rike)|i(n|zeToContent|debar|gnText)|ort|u(p|b(str(ing)?)?)|pli(ce|t)|e(nd|t(Re(sizable|questHeader)|M(i(nutes|lliseconds)|onth)|Seconds|Ho(tKeys|urs)|Year|Cursor|Time(out)?|Interval|ZOptions|Date|UTC(M(i(nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(ome|andleEvent)|navigate|c(har(CodeAt|At)|o(s|n(cat|textual|firm)|mpile)|eil|lear(Timeout|Interval)?|a(ptureEvents|ll)|reate(StyleSheet|Popup|EventObject))|t(o(GMTString|S(tring|ource)|U(TCString|pperCase)|Lo(caleString|werCase))|est|a(n|int(Enabled)?))|i(s(NaN|Finite)|ndexOf|talics)|d(isableExternalCapture|ump|etachEvent)|u(n(shift|taint|escape|watch)|pdateCommands)|j(oin|avaEnabled)|p(o(p|w)|ush|lugins.refresh|a(ddings|rse(Int|Float)?)|r(int|ompt|eference))|e(scape|nableExternalCapture|val|lementFromPoint|x(p|ec(Script|Command)?))|valueOf|UTC|queryCommand(State|Indeterm|Enabled|Value)|f(i(nd|le(ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(nt(size|color)|rward)|loor|romCharCode)|watch|l(ink|o(ad|g)|astIndexOf)|a(sin|nchor|cos|t(tachEvent|ob|an(2)?)|pply|lert|b(s|ort))|r(ou(nd|teEvents)|e(size(By|To)|calc|turnValue|place|verse|l(oad|ease(Capture|Events)))|andom)|g(o|et(ResponseHeader|M(i(nutes|lliseconds)|onth)|Se(conds|lection)|Hours|Year|Time(zoneOffset)?|Da(y|te)|UTC(M(i(nutes|lliseconds)|onth)|Seconds|Hours|Da(y|te)|FullYear)|FullYear|A(ttention|llResponseHeaders)))|m(in|ove(B(y|elow)|To(Absolute)?|Above)|ergeAttributes|a(tch|rgins|x))|b(toa|ig|o(ld|rderWidths)|link|ack))\b(?=\()',
+ name: support.function.chai}
+- {match: '\b(s(ub(stringData|mit)|plitText|e(t(NamedItem|Attribute(Node)?)|lect))|has(ChildNodes|Feature)|namedItem|c(l(ick|o(se|neNode))|reate(C(omment|DATASection|aption)|T(Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(ntityReference|lement)|Attribute))|tabIndex|i(nsert(Row|Before|Cell|Data)|tem)|open|delete(Row|C(ell|aption)|T(Head|Foot)|Data)|focus|write(ln)?|a(dd|ppend(Child|Data))|re(set|place(Child|Data)|move(NamedItem|Child|Attribute(Node)?)?)|get(NamedItem|Element(sBy(Name|TagName)|ById)|Attribute(Node)?)|blur)\b(?=\()',
+ name: support.function.dom.chai}
+- {match: '(?<=\.)(s(ystemLanguage|cr(ipts|ollbars|een(X|Y|Top|Left))|t(yle(Sheets)?|atus(Text|bar)?)|ibling(Below|Above)|ource|uffixes|e(curity(Policy)?|l(ection|f)))|h(istory|ost(name)?|as(h|Focus))|y|X(MLDocument|SLDocument)|n(ext|ame(space(s|URI)|Prop))|M(IN_VALUE|AX_VALUE)|c(haracterSet|o(n(structor|trollers)|okieEnabled|lorDepth|mp(onents|lete))|urrent|puClass|l(i(p(boardData)?|entInformation)|osed|asses)|alle(e|r)|rypto)|t(o(olbar|p)|ext(Transform|Indent|Decoration|Align)|ags)|SQRT(1_2|2)|i(n(ner(Height|Width)|put)|ds|gnoreCase)|zIndex|o(scpu|n(readystatechange|Line)|uter(Height|Width)|p(sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(i(splay|alog(Height|Top|Width|Left|Arguments)|rectories)|e(scription|fault(Status|Ch(ecked|arset)|View)))|u(ser(Profile|Language|Agent)|n(iqueID|defined)|pdateInterval)|_content|p(ixelDepth|ort|ersonalbar|kcs11|l(ugins|atform)|a(thname|dding(Right|Bottom|Top|Left)|rent(Window|Layer)?|ge(X(Offset)?|Y(Offset)?))|r(o(to(col|type)|duct(Sub)?|mpter)|e(vious|fix)))|e(n(coding|abledPlugin)|x(ternal|pando)|mbeds)|v(isibility|endor(Sub)?|Linkcolor)|URLUnencoded|P(I|OSITIVE_INFINITY)|f(ilename|o(nt(Size|Family|Weight)|rmName)|rame(s|Element)|gColor)|E|whiteSpace|l(i(stStyleType|n(eHeight|kColor))|o(ca(tion(bar)?|lName)|wsrc)|e(ngth|ft(Context)?)|a(st(M(odified|atch)|Index|Paren)|yer(s|X)|nguage))|a(pp(MinorVersion|Name|Co(deName|re)|Version)|vail(Height|Top|Width|Left)|ll|r(ity|guments)|Linkcolor|bove)|r(ight(Context)?|e(sponse(XML|Text)|adyState))|global|x|m(imeTypes|ultiline|enubar|argin(Right|Bottom|Top|Left))|L(N(10|2)|OG(10E|2E))|b(o(ttom|rder(Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(Color|Image)))\b',
+ name: support.constant.chai}
+- {match: '(?<=\.)(s(hape|ystemId|c(heme|ope|rolling)|ta(ndby|rt)|ize|ummary|pecified|e(ctionRowIndex|lected(Index)?)|rc)|h(space|t(tpEquiv|mlFor)|e(ight|aders)|ref(lang)?)|n(o(Resize|tation(s|Name)|Shade|Href|de(Name|Type|Value)|Wrap)|extSibling|ame)|c(h(ildNodes|Off|ecked|arset)?|ite|o(ntent|o(kie|rds)|de(Base|Type)?|l(s|Span|or)|mpact)|ell(s|Spacing|Padding)|l(ear|assName)|aption)|t(ype|Bodies|itle|Head|ext|a(rget|gName)|Foot)|i(sMap|ndex|d|m(plementation|ages))|o(ptions|wnerDocument|bject)|d(i(sabled|r)|o(c(type|umentElement)|main)|e(clare|f(er|ault(Selected|Checked|Value)))|at(eTime|a))|useMap|p(ublicId|arentNode|r(o(file|mpt)|eviousSibling))|e(n(ctype|tities)|vent|lements)|v(space|ersion|alue(Type)?|Link|Align)|URL|f(irstChild|orm(s)?|ace|rame(Border)?)|width|l(ink(s)?|o(ngDesc|wSrc)|a(stChild|ng|bel))|a(nchors|c(ce(ssKey|pt(Charset)?)|tion)|ttributes|pplets|l(t|ign)|r(chive|eas)|xis|Link|bbr)|r(ow(s|Span|Index)|ules|e(v|ferrer|l|adOnly))|m(ultiple|e(thod|dia)|a(rgin(Height|Width)|xLength))|b(o(dy|rder)|ackground|gColor))\b',
+ name: support.constant.dom.chai}
+- {match: \b(ELEMENT_NODE|ATTRIBUTE_NODE|TEXT_NODE|CDATA_SECTION_NODE|ENTITY_REFERENCE_NODE|ENTITY_NODE|PROCESSING_INSTRUCTION_NODE|COMMENT_NODE|DOCUMENT_NODE|DOCUMENT_TYPE_NODE|DOCUMENT_FRAGMENT_NODE|NOTATION_NODE|INDEX_SIZE_ERR|DOMSTRING_SIZE_ERR|HIERARCHY_REQUEST_ERR|WRONG_DOCUMENT_ERR|INVALID_CHARACTER_ERR|NO_DATA_ALLOWED_ERR|NO_MODIFICATION_ALLOWED_ERR|NOT_FOUND_ERR|NOT_SUPPORTED_ERR|INUSE_ATTRIBUTE_ERR)\b,
+ name: support.constant.dom.chai}
+- {match: '\bon(R(ow(s(inserted|delete)|e(nter|xit))|e(s(ize(start|end)?|et)|adystatechange))|Mouse(o(ut|ver)|down|up|move)|B(efore(cut|deactivate|u(nload|pdate)|p(aste|rint)|editfocus|activate)|lur)|S(croll|top|ubmit|elect(start|ionchange)?)|H(over|elp)|C(hange|ont(extmenu|rolselect)|ut|ellchange|l(ick|ose))|D(eactivate|ata(setc(hanged|omplete)|available)|r(op|ag(start|over|drop|en(ter|d)|leave)?)|blclick)|Unload|P(aste|ropertychange)|Error(update)?|Key(down|up|press)|Focus|Load|A(ctivate|fter(update|print)|bort))\b',
+ name: support.function.event-handler.chai}
+- {match: '!|\$|%|&|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|(?
+
+
+
+ comment
+ ChaiScript Syntax: version 2.0
+ fileTypes
+
+ chai
+
+ firstLineMatch
+ ^#!/usr/bin/env node
+ foldingStartMarker
+ ^.*\bdef\s*(\w+\s*)?\([^\)]*\)(\s*\{[^\}]*)?\s*$
+ foldingStopMarker
+ ^\s*\}
+ keyEquivalent
+ ^~J
+ name
+ ChaiScript
+ patterns
+
+
+ comment
+ chaiscript shebang
+ match
+ ^#
+ name
+ comment.line.chai
+
+
+ match
+ \b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?))\b
+ name
+ constant.numeric.chai
+
+
+ begin
+ '
+ beginCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.begin.chai
+
+
+ end
+ '
+ endCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.end.chai
+
+
+ name
+ string.quoted.single.chai
+ patterns
+
+
+ match
+ \\(x\h{2}|[0-2][0-7]{,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)
+ name
+ constant.character.escape.chai
+
+
+
+
+ begin
+ "
+ beginCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.begin.chai
+
+
+ end
+ "
+ endCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.end.chai
+
+
+ name
+ string.quoted.double.chai
+ patterns
+
+
+ match
+ \\(x\h{2}|[0-2][0-7]{,2}|3[0-6][0-7]|37[0-7]?|[4-7][0-7]?|.)
+ name
+ constant.character.escape.chai
+
+
+
+
+ begin
+ /\*\*(?!/)
+ captures
+
+ 0
+
+ name
+ punctuation.definition.comment.chai
+
+
+ end
+ \*/
+ name
+ comment.block.documentation.chai
+
+
+ begin
+ /\*
+ captures
+
+ 0
+
+ name
+ punctuation.definition.comment.chai
+
+
+ end
+ \*/
+ name
+ comment.block.chai
+
+
+ captures
+
+ 1
+
+ name
+ punctuation.definition.comment.chai
+
+
+ match
+ (//).*$\n?
+ name
+ comment.line.double-slash.chai
+
+
+ captures
+
+ 0
+
+ name
+ punctuation.definition.comment.html.chai
+
+ 2
+
+ name
+ punctuation.definition.comment.html.chai
+
+
+ match
+ (<!--|-->)
+ name
+ comment.block.html.chai
+
+
+ match
+ \b(boolean|byte|char|class|double|enum|float|fun|def|int|interface|long|short|var|auto|attr)\b
+ name
+ storage.type.chai
+
+
+ match
+ \b(break|case|catch|continue|default|do|else|finally|else if|for|goto|if|return|switch|throw|try|while)\b
+ name
+ keyword.control.chai
+
+
+ match
+ \b(delete|in|instanceof|new|typeof|with)\b
+ name
+ keyword.operator.chai
+
+
+ match
+ \btrue\b
+ name
+ constant.language.boolean.true.chai
+
+
+ match
+ \bfalse\b
+ name
+ constant.language.boolean.false.chai
+
+
+ match
+ \bnull\b
+ name
+ constant.language.null.chai
+
+
+ match
+ \b(Anchor|Applet|Area|Array|Boolean|Button|Checkbox|Date|document|event|FileUpload|Form|Frame|Function|Hidden|History|Image|JavaArray|JavaClass|JavaObject|JavaPackage|java|Layer|Link|Location|Math|MimeType|Number|navigator|netscape|Object|Option|Packages|Password|Plugin|Radio|RegExp|Reset|Select|String|Style|Submit|screen|sun|Text|Textarea|window|XMLHttpRequest)\b
+ name
+ support.class.chai
+
+
+ match
+ \b(s(h(ift|ow(Mod(elessDialog|alDialog)|Help))|croll(X|By(Pages|Lines)?|Y|To)?|t(op|rike)|i(n|zeToContent|debar|gnText)|ort|u(p|b(str(ing)?)?)|pli(ce|t)|e(nd|t(Re(sizable|questHeader)|M(i(nutes|lliseconds)|onth)|Seconds|Ho(tKeys|urs)|Year|Cursor|Time(out)?|Interval|ZOptions|Date|UTC(M(i(nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(ome|andleEvent)|navigate|c(har(CodeAt|At)|o(s|n(cat|textual|firm)|mpile)|eil|lear(Timeout|Interval)?|a(ptureEvents|ll)|reate(StyleSheet|Popup|EventObject))|t(o(GMTString|S(tring|ource)|U(TCString|pperCase)|Lo(caleString|werCase))|est|a(n|int(Enabled)?))|i(s(NaN|Finite)|ndexOf|talics)|d(isableExternalCapture|ump|etachEvent)|u(n(shift|taint|escape|watch)|pdateCommands)|j(oin|avaEnabled)|p(o(p|w)|ush|lugins.refresh|a(ddings|rse(Int|Float)?)|r(int|ompt|eference))|e(scape|nableExternalCapture|val|lementFromPoint|x(p|ec(Script|Command)?))|valueOf|UTC|queryCommand(State|Indeterm|Enabled|Value)|f(i(nd|le(ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(nt(size|color)|rward)|loor|romCharCode)|watch|l(ink|o(ad|g)|astIndexOf)|a(sin|nchor|cos|t(tachEvent|ob|an(2)?)|pply|lert|b(s|ort))|r(ou(nd|teEvents)|e(size(By|To)|calc|turnValue|place|verse|l(oad|ease(Capture|Events)))|andom)|g(o|et(ResponseHeader|M(i(nutes|lliseconds)|onth)|Se(conds|lection)|Hours|Year|Time(zoneOffset)?|Da(y|te)|UTC(M(i(nutes|lliseconds)|onth)|Seconds|Hours|Da(y|te)|FullYear)|FullYear|A(ttention|llResponseHeaders)))|m(in|ove(B(y|elow)|To(Absolute)?|Above)|ergeAttributes|a(tch|rgins|x))|b(toa|ig|o(ld|rderWidths)|link|ack))\b(?=\()
+ name
+ support.function.chai
+
+
+ match
+ \b(s(ub(stringData|mit)|plitText|e(t(NamedItem|Attribute(Node)?)|lect))|has(ChildNodes|Feature)|namedItem|c(l(ick|o(se|neNode))|reate(C(omment|DATASection|aption)|T(Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(ntityReference|lement)|Attribute))|tabIndex|i(nsert(Row|Before|Cell|Data)|tem)|open|delete(Row|C(ell|aption)|T(Head|Foot)|Data)|focus|write(ln)?|a(dd|ppend(Child|Data))|re(set|place(Child|Data)|move(NamedItem|Child|Attribute(Node)?)?)|get(NamedItem|Element(sBy(Name|TagName)|ById)|Attribute(Node)?)|blur)\b(?=\()
+ name
+ support.function.dom.chai
+
+
+ match
+ (?<=\.)(s(ystemLanguage|cr(ipts|ollbars|een(X|Y|Top|Left))|t(yle(Sheets)?|atus(Text|bar)?)|ibling(Below|Above)|ource|uffixes|e(curity(Policy)?|l(ection|f)))|h(istory|ost(name)?|as(h|Focus))|y|X(MLDocument|SLDocument)|n(ext|ame(space(s|URI)|Prop))|M(IN_VALUE|AX_VALUE)|c(haracterSet|o(n(structor|trollers)|okieEnabled|lorDepth|mp(onents|lete))|urrent|puClass|l(i(p(boardData)?|entInformation)|osed|asses)|alle(e|r)|rypto)|t(o(olbar|p)|ext(Transform|Indent|Decoration|Align)|ags)|SQRT(1_2|2)|i(n(ner(Height|Width)|put)|ds|gnoreCase)|zIndex|o(scpu|n(readystatechange|Line)|uter(Height|Width)|p(sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(i(splay|alog(Height|Top|Width|Left|Arguments)|rectories)|e(scription|fault(Status|Ch(ecked|arset)|View)))|u(ser(Profile|Language|Agent)|n(iqueID|defined)|pdateInterval)|_content|p(ixelDepth|ort|ersonalbar|kcs11|l(ugins|atform)|a(thname|dding(Right|Bottom|Top|Left)|rent(Window|Layer)?|ge(X(Offset)?|Y(Offset)?))|r(o(to(col|type)|duct(Sub)?|mpter)|e(vious|fix)))|e(n(coding|abledPlugin)|x(ternal|pando)|mbeds)|v(isibility|endor(Sub)?|Linkcolor)|URLUnencoded|P(I|OSITIVE_INFINITY)|f(ilename|o(nt(Size|Family|Weight)|rmName)|rame(s|Element)|gColor)|E|whiteSpace|l(i(stStyleType|n(eHeight|kColor))|o(ca(tion(bar)?|lName)|wsrc)|e(ngth|ft(Context)?)|a(st(M(odified|atch)|Index|Paren)|yer(s|X)|nguage))|a(pp(MinorVersion|Name|Co(deName|re)|Version)|vail(Height|Top|Width|Left)|ll|r(ity|guments)|Linkcolor|bove)|r(ight(Context)?|e(sponse(XML|Text)|adyState))|global|x|m(imeTypes|ultiline|enubar|argin(Right|Bottom|Top|Left))|L(N(10|2)|OG(10E|2E))|b(o(ttom|rder(Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(Color|Image)))\b
+ name
+ support.constant.chai
+
+
+ match
+ (?<=\.)(s(hape|ystemId|c(heme|ope|rolling)|ta(ndby|rt)|ize|ummary|pecified|e(ctionRowIndex|lected(Index)?)|rc)|h(space|t(tpEquiv|mlFor)|e(ight|aders)|ref(lang)?)|n(o(Resize|tation(s|Name)|Shade|Href|de(Name|Type|Value)|Wrap)|extSibling|ame)|c(h(ildNodes|Off|ecked|arset)?|ite|o(ntent|o(kie|rds)|de(Base|Type)?|l(s|Span|or)|mpact)|ell(s|Spacing|Padding)|l(ear|assName)|aption)|t(ype|Bodies|itle|Head|ext|a(rget|gName)|Foot)|i(sMap|ndex|d|m(plementation|ages))|o(ptions|wnerDocument|bject)|d(i(sabled|r)|o(c(type|umentElement)|main)|e(clare|f(er|ault(Selected|Checked|Value)))|at(eTime|a))|useMap|p(ublicId|arentNode|r(o(file|mpt)|eviousSibling))|e(n(ctype|tities)|vent|lements)|v(space|ersion|alue(Type)?|Link|Align)|URL|f(irstChild|orm(s)?|ace|rame(Border)?)|width|l(ink(s)?|o(ngDesc|wSrc)|a(stChild|ng|bel))|a(nchors|c(ce(ssKey|pt(Charset)?)|tion)|ttributes|pplets|l(t|ign)|r(chive|eas)|xis|Link|bbr)|r(ow(s|Span|Index)|ules|e(v|ferrer|l|adOnly))|m(ultiple|e(thod|dia)|a(rgin(Height|Width)|xLength))|b(o(dy|rder)|ackground|gColor))\b
+ name
+ support.constant.dom.chai
+
+
+ match
+ \b(ELEMENT_NODE|ATTRIBUTE_NODE|TEXT_NODE|CDATA_SECTION_NODE|ENTITY_REFERENCE_NODE|ENTITY_NODE|PROCESSING_INSTRUCTION_NODE|COMMENT_NODE|DOCUMENT_NODE|DOCUMENT_TYPE_NODE|DOCUMENT_FRAGMENT_NODE|NOTATION_NODE|INDEX_SIZE_ERR|DOMSTRING_SIZE_ERR|HIERARCHY_REQUEST_ERR|WRONG_DOCUMENT_ERR|INVALID_CHARACTER_ERR|NO_DATA_ALLOWED_ERR|NO_MODIFICATION_ALLOWED_ERR|NOT_FOUND_ERR|NOT_SUPPORTED_ERR|INUSE_ATTRIBUTE_ERR)\b
+ name
+ support.constant.dom.chai
+
+
+ match
+ \bon(R(ow(s(inserted|delete)|e(nter|xit))|e(s(ize(start|end)?|et)|adystatechange))|Mouse(o(ut|ver)|down|up|move)|B(efore(cut|deactivate|u(nload|pdate)|p(aste|rint)|editfocus|activate)|lur)|S(croll|top|ubmit|elect(start|ionchange)?)|H(over|elp)|C(hange|ont(extmenu|rolselect)|ut|ellchange|l(ick|ose))|D(eactivate|ata(setc(hanged|omplete)|available)|r(op|ag(start|over|drop|en(ter|d)|leave)?)|blclick)|Unload|P(aste|ropertychange)|Error(update)?|Key(down|up|press)|Focus|Load|A(ctivate|fter(update|print)|bort))\b
+ name
+ support.function.event-handler.chai
+
+
+ match
+ !|\$|%|&|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|(?<!\()/=|%=|\+=|\-=|&=|\^=|\b(in|instanceof|new|delete|typeof|void)\b
+ name
+ keyword.operator.chai
+
+
+ match
+ \b(Infinity|NaN|undefined)\b
+ name
+ constant.language.chai
+
+
+ begin
+ (?<=[=(:]|^|return|&&|\|\||!)\s*(/)(?![/*+{}?])
+ beginCaptures
+
+ 1
+
+ name
+ punctuation.definition.string.begin.chai
+
+
+ end
+ (/)[igm]*
+ endCaptures
+
+ 1
+
+ name
+ punctuation.definition.string.end.chai
+
+
+ name
+ string.regexp.chai
+ patterns
+
+
+ match
+ \\.
+ name
+ constant.character.escape.chai
+
+
+
+
+ match
+ \;
+ name
+ punctuation.terminator.statement.chai
+
+
+ match
+ ,[ |\t]*
+ name
+ meta.delimiter.object.comma.chai
+
+
+ match
+ \.
+ name
+ meta.delimiter.method.period.chai
+
+
+ match
+ \{|\}
+ name
+ meta.brace.curly.chai
+
+
+ match
+ \(|\)
+ name
+ meta.brace.round.chai
+
+
+ match
+ \[|\]
+ name
+ meta.brace.square.chai
+
+
+ scopeName
+ source.chai
+ uuid
+ 93E017CC-6F27-11D9-90EB-000D93589AF6
+
+
diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp
index 15b4a64..6bac83a 100644
--- a/include/chaiscript/chaiscript_threading.hpp
+++ b/include/chaiscript/chaiscript_threading.hpp
@@ -7,6 +7,7 @@
#ifndef CHAISCRIPT_THREADING_HPP_
#define CHAISCRIPT_THREADING_HPP_
+
#include
#ifndef CHAISCRIPT_NO_THREADS
@@ -16,6 +17,8 @@
#pragma message ("ChaiScript is compiling without thread safety.")
#endif
+#include "chaiscript_defines.hpp"
+
/// \file
///
/// This file contains code necessary for thread support in ChaiScript.
diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp
index f7177f4..32c11c1 100644
--- a/include/chaiscript/dispatchkit/bootstrap.hpp
+++ b/include/chaiscript/dispatchkit/bootstrap.hpp
@@ -136,10 +136,14 @@ namespace chaiscript
ModulePtr bootstrap_pod_type(const std::string &name, ModulePtr m = ModulePtr(new Module()))
{
m->add(user_type(), name);
- m->add(constructor(), name);
+ m->add(constructor(), name);
construct_pod(name, m);
- m->add(fun(&to_string), "to_string");
+ auto to_s = fun(&to_string);
+
+ if (!m->has_function(to_s, "to_string")) {
+ m->add(to_s, "to_string");
+ }
m->add(fun(&parse_string), "to_" + name);
return m;
}
@@ -471,7 +475,6 @@ namespace chaiscript
m->add(chaiscript::fun(&has_parse_tree), "has_parse_tree");
m->add(chaiscript::fun(&get_parse_tree), "get_parse_tree");
- m->add(chaiscript::user_type(), "eval_error");
m->add(chaiscript::base_class());
m->add(chaiscript::user_type(), "arithmetic_error");
diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp
index d1330c9..cc4219c 100644
--- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp
+++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp
@@ -267,7 +267,7 @@ namespace chaiscript
template
ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module()))
{
- basic_constructors(type, m);
+ copy_constructor(type, m);
operators::assign(m);
return m;
}
@@ -443,6 +443,7 @@ namespace chaiscript
m->add(fun(static_cast(&MapType::operator[])), "[]");
container_type(type, m);
+ default_constructible_type(type, m);
assignable_type(type, m);
unique_associative_container_type(type, m);
pair_associative_container_type(type, m);
diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp
index a71c7cd..c218d30 100644
--- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp
+++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp
@@ -65,21 +65,11 @@ namespace chaiscript
typedef const Result * Result_Type;
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *)
{
- if (ob.is_ref())
+ if (ob.get_type_info().bare_equal_type_info(typeid(Result)))
{
- if (!ob.get_type_info().is_const())
- {
- return &(ob.get().cast >()).get();
- } else {
- return &(ob.get().cast >()).get();
- }
+ return static_cast(throw_if_null(ob.get_const_ptr()));
} else {
- if (!ob.get_type_info().is_const())
- {
- return (ob.get().cast >()).get();
- } else {
- return (ob.get().cast >()).get();
- }
+ throw chaiscript::detail::exception::bad_any_cast();
}
}
};
@@ -101,6 +91,7 @@ namespace chaiscript
};
+
/// Cast_Helper_Inner for casting to a & type
template
struct Cast_Helper_Inner
diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp
index 9cf53d9..3c9dabe 100644
--- a/include/chaiscript/dispatchkit/dispatchkit.hpp
+++ b/include/chaiscript/dispatchkit/dispatchkit.hpp
@@ -199,6 +199,14 @@ namespace chaiscript
{
}
+ bool has_function(const Proxy_Function &new_f, const std::string &name)
+ {
+ return std::any_of(m_funcs.begin(), m_funcs.end(), [&](const std::pair &existing_f) {
+ return existing_f.second == name && *(existing_f.first) == *(new_f);
+ });
+ }
+
+
private:
std::vector > m_typeinfos;
std::vector > m_funcs;
@@ -580,7 +588,7 @@ namespace chaiscript
}
/// Returns the type info for a named type
- Type_Info get_type(const std::string &name) const
+ Type_Info get_type(const std::string &name, bool t_throw = true) const
{
chaiscript::detail::threading::shared_lock l(m_mutex);
@@ -591,7 +599,11 @@ namespace chaiscript
return itr->second;
}
- throw std::range_error("Type Not Known");
+ if (t_throw) {
+ throw std::range_error("Type Not Known");
+ } else {
+ return Type_Info();
+ }
}
/// Returns the registered name of a known type_info object
@@ -1018,14 +1030,6 @@ namespace chaiscript
static bool function_less_than(const Proxy_Function &lhs, const Proxy_Function &rhs)
{
- const auto &lhsparamtypes = lhs->get_param_types();
- const auto &rhsparamtypes = rhs->get_param_types();
-
- const auto lhssize = lhsparamtypes.size();
- const auto rhssize = rhsparamtypes.size();
-
- CHAISCRIPT_CONSTEXPR auto boxed_type = user_type();
- CHAISCRIPT_CONSTEXPR auto boxed_pod_type = user_type();
auto dynamic_lhs(std::dynamic_pointer_cast(lhs));
auto dynamic_rhs(std::dynamic_pointer_cast(rhs));
@@ -1055,6 +1059,14 @@ namespace chaiscript
return true;
}
+ const auto &lhsparamtypes = lhs->get_param_types();
+ const auto &rhsparamtypes = rhs->get_param_types();
+
+ const auto lhssize = lhsparamtypes.size();
+ const auto rhssize = rhsparamtypes.size();
+
+ CHAISCRIPT_CONSTEXPR auto boxed_type = user_type();
+ CHAISCRIPT_CONSTEXPR auto boxed_pod_type = user_type();
for (size_t i = 1; i < lhssize && i < rhssize; ++i)
{
diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp
index 36e8dff..67c9543 100644
--- a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp
+++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp
@@ -57,7 +57,7 @@ namespace chaiscript
const Proxy_Function &t_func,
const Type_Info &t_ti)
: Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti), t_func->get_arity()),
- m_type_name(std::move(t_type_name)), m_func(t_func), m_ti(new Type_Info(t_ti)), m_doti(user_type())
+ m_type_name(std::move(t_type_name)), m_func(t_func), m_ti(t_ti.is_undef()?nullptr:new Type_Info(t_ti)), m_doti(user_type())
{
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp
index a9e1164..9e7c0c2 100644
--- a/include/chaiscript/dispatchkit/handle_return.hpp
+++ b/include/chaiscript/dispatchkit/handle_return.hpp
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include "boxed_number.hpp"
#include "boxed_value.hpp"
@@ -33,15 +34,19 @@ namespace chaiscript
template
struct Handle_Return
{
- static Boxed_Value handle(const Ret &r)
- {
- return const_var(r);
- }
-
- static Boxed_Value handle(Ret &&r)
+ template::type>::value>::type>
+ static Boxed_Value handle(T r)
{
return Boxed_Value(std::move(r));
}
+
+ template::type>::value>::type>
+ static Boxed_Value handle(T &&r)
+ {
+ return Boxed_Value(std::make_shared(std::forward(r)));
+ }
};
template
diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp
index d03c33d..1f71ad5 100644
--- a/include/chaiscript/dispatchkit/proxy_functions.hpp
+++ b/include/chaiscript/dispatchkit/proxy_functions.hpp
@@ -529,12 +529,7 @@ namespace chaiscript
virtual bool call_match(const std::vector &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{
- if (static_cast(vals.size()) != get_arity())
- {
- return false;
- }
-
- return compare_types(m_types, vals) || compare_types_with_cast(vals, t_conversions);
+ return static_cast(vals.size()) == get_arity() && (compare_types(m_types, vals) || compare_types_with_cast(vals, t_conversions));
}
virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions &t_conversions) const = 0;
@@ -722,8 +717,18 @@ namespace chaiscript
{
matching_func = begin;
} else {
- // More than one function matches, not attempting
- throw exception::dispatch_error(plist, std::vector(orig, end));
+ // handle const members vs non-const member, which is not really ambiguous
+ const auto &mat_fun_param_types = (*matching_func)->get_param_types();
+ const auto &next_fun_param_types = (*begin)->get_param_types();
+
+ if (plist[0].is_const() && !mat_fun_param_types[1].is_const() && next_fun_param_types[1].is_const()) {
+ matching_func = begin; // keep the new one, the const/non-const matchup is correct
+ } else if (!plist[0].is_const() && !mat_fun_param_types[1].is_const() && next_fun_param_types[1].is_const()) {
+ // keep the old one, it has a better const/non-const matchup
+ } else {
+ // ambiguous function call
+ throw exception::dispatch_error(plist, std::vector(orig, end));
+ }
}
}
@@ -808,12 +813,6 @@ namespace chaiscript
return (*(func.second))(plist, t_conversions);
}
} catch (const exception::bad_boxed_cast &) {
- //std::cout << "Bad Boxed Cast: " << func.second->get_arity() << '(';
- //for (const auto &p : plist) {
- // std::cout << p.get_type_info().name() << ',';
- //}
- //std::cout << ")\n";
-
//parameter failed to cast, try again
} catch (const exception::arity_error &) {
//invalid num params, try again
diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp
index 13eb680..dc29efe 100644
--- a/include/chaiscript/dispatchkit/type_conversions.hpp
+++ b/include/chaiscript/dispatchkit/type_conversions.hpp
@@ -119,24 +119,27 @@ namespace chaiscript
// Dynamic cast out the contained boxed value, which we know is the type we want
if (t_from.is_const())
{
- std::shared_ptr data
- = std::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_from, nullptr));
- if (!data)
- {
- throw std::bad_cast();
- }
-
- return Boxed_Value(data);
+ return Boxed_Value(
+ [&]()->std::shared_ptr{
+ if (auto data = std::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_from, nullptr)))
+ {
+ return data;
+ } else {
+ throw std::bad_cast();
+ }
+ }()
+ );
} else {
- std::shared_ptr data
- = std::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_from, nullptr));
-
- if (!data)
- {
- throw std::bad_cast();
- }
-
- return Boxed_Value(data);
+ return Boxed_Value(
+ [&]()->std::shared_ptr{
+ if (auto data = std::dynamic_pointer_cast(detail::Cast_Helper >::cast(t_from, nullptr)))
+ {
+ return data;
+ } else {
+ throw std::bad_cast();
+ }
+ }()
+ );
}
} else {
// Pull the reference out of the contained boxed value, which we know is the type we want
@@ -439,9 +442,7 @@ namespace chaiscript
static_assert(std::is_convertible::value, "Types are not automatically convertible");
auto func = [](const Boxed_Value &t_bv) -> Boxed_Value {
// not even attempting to call boxed_cast so that we don't get caught in some call recursion
- auto &&from = detail::Cast_Helper::cast(t_bv, nullptr);
- To to(from);
- return chaiscript::Boxed_Value(to);
+ return chaiscript::Boxed_Value(To(detail::Cast_Helper::cast(t_bv, nullptr)));
};
return std::make_shared>(user_type(), user_type(), func);
diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp
index 9195fb2..82f3a52 100644
--- a/include/chaiscript/language/chaiscript_common.hpp
+++ b/include/chaiscript/language/chaiscript_common.hpp
@@ -499,7 +499,7 @@ namespace chaiscript
struct Return_Value {
Boxed_Value retval;
- Return_Value(const Boxed_Value &t_return_value) : retval(t_return_value) { }
+ Return_Value(Boxed_Value t_return_value) : retval(std::move(t_return_value)) { }
};
diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp
index a266bc6..9ee75d6 100644
--- a/include/chaiscript/language/chaiscript_engine.hpp
+++ b/include/chaiscript/language/chaiscript_engine.hpp
@@ -297,6 +297,15 @@ namespace chaiscript
}
}
+ /// Evaluates the given string, used during eval() inside of a script
+ const Boxed_Value internal_eval_file(const std::string &t_filename) {
+ try {
+ return do_eval(load_file(t_filename), t_filename, true);
+ } catch (const exception::eval_error &t_ee) {
+ throw Boxed_Value(t_ee);
+ }
+ }
+
/// Evaluates the given string, used during eval() inside of a script
@@ -353,7 +362,9 @@ namespace chaiscript
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, std::ref(m_engine)), "name");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type, std::ref(m_engine)), "type");
- m_engine.add(fun &)> (
+ m_engine.add(fun([this](const std::string &t_type_name){ return this->m_engine.get_type(t_type_name, true); }), "type");
+
+ m_engine.add(fun &)>(
[=](const Type_Info &t_from, const Type_Info &t_to, const std::function &t_func) {
m_engine.add(chaiscript::type_conversion(t_from, t_to, t_func));
}
@@ -367,6 +378,7 @@ namespace chaiscript
m_engine.add(fun(static_cast(&ChaiScript::load_module), this), "load_module");
m_engine.add(fun(&ChaiScript::use, this), "use");
+ m_engine.add(fun(&ChaiScript::internal_eval_file, this), "eval_file");
m_engine.add(fun(&ChaiScript::internal_eval, this), "eval");
m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval");
@@ -455,7 +467,7 @@ namespace chaiscript
union cast_union
{
- void (ChaiScript::*in_ptr)(const std::string&);
+ Boxed_Value (ChaiScript::*in_ptr)(const std::string&);
void *out_ptr;
};
@@ -529,7 +541,7 @@ namespace chaiscript
/// requested file.
///
/// \param[in] t_filename Filename to load and evaluate
- void use(const std::string &t_filename)
+ Boxed_Value use(const std::string &t_filename)
{
for (const auto &path : m_usepaths)
{
@@ -539,15 +551,17 @@ namespace chaiscript
chaiscript::detail::threading::unique_lock l(m_use_mutex);
chaiscript::detail::threading::unique_lock l2(m_mutex);
+ Boxed_Value retval;
+
if (m_used_files.count(appendedpath) == 0)
{
l2.unlock();
- eval_file(appendedpath);
+ retval = eval_file(appendedpath);
l2.lock();
m_used_files.insert(appendedpath);
- }
+ }
- return; // return, we loaded it, or it was already loaded
+ return retval; // return, we loaded it, or it was already loaded
} catch (const exception::file_not_found_error &) {
// failed to load, try the next path
}
diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp
index 06f2b13..0b1c564 100644
--- a/include/chaiscript/language/chaiscript_eval.hpp
+++ b/include/chaiscript/language/chaiscript_eval.hpp
@@ -61,7 +61,7 @@ namespace chaiscript
try {
return t_node->eval(t_ss);
} catch (detail::Return_Value &rv) {
- return rv.retval;
+ return std::move(rv.retval);
}
}
}
@@ -517,11 +517,7 @@ namespace chaiscript
{
return std::pair();
} else {
- try {
- return std::pair(t_node->children[0]->text, t_ss.get_type(t_node->children[0]->text));
- } catch (const std::range_error &) {
- return std::pair(t_node->children[0]->text, Type_Info());
- }
+ return std::pair(t_node->children[0]->text, t_ss.get_type(t_node->children[0]->text, false));
}
}
@@ -707,13 +703,14 @@ namespace chaiscript
fpp.save_params(params);
- std::string fun_name;
- if ((this->children[i]->identifier == AST_Node_Type::Fun_Call) || (this->children[i]->identifier == AST_Node_Type::Array_Call)) {
- fun_name = this->children[i]->children[0]->text;
- }
- else {
- fun_name = this->children[i]->text;
- }
+ std::string fun_name = [&](){
+ if ((this->children[i]->identifier == AST_Node_Type::Fun_Call) || (this->children[i]->identifier == AST_Node_Type::Array_Call)) {
+ return this->children[i]->children[0]->text;
+ }
+ else {
+ return this->children[i]->text;
+ }
+ }();
try {
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
@@ -728,7 +725,7 @@ namespace chaiscript
}
}
catch(detail::Return_Value &rv) {
- retval = rv.retval;
+ retval = std::move(rv.retval);
}
if (this->children[i]->identifier == AST_Node_Type::Array_Call) {
@@ -1171,14 +1168,11 @@ namespace chaiscript
AST_Node(std::move(t_ast_node_text), AST_Node_Type::File, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~File_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
- const size_t size = this->children.size();
- for (size_t i = 0; i < size; ++i) {
- Boxed_Value retval(this->children[i]->eval(t_ss));
- if (i + 1 == size) {
- return retval;
- }
+ const auto num_children = children.size();
+ for (size_t i = 0; i < num_children-1; ++i) {
+ children[i]->eval(t_ss);
}
- return Boxed_Value();
+ return children.back()->eval(t_ss);
}
};
@@ -1486,30 +1480,19 @@ namespace chaiscript
static_cast(numparams), this->children.back(), param_types, l_annotation, guard)),
function_name);
- }
- else {
- try {
- // Do know type name (if this line fails, the catch block is called and the
- // other version is called, with no Type_Info object known)
- auto type = t_ss.get_type(class_name);
- param_types.push_front(class_name, type);
+ } else {
- t_ss.add(
- std::make_shared(class_name,
- std::make_shared(std::bind(chaiscript::eval::detail::eval_function,
- std::ref(t_ss), this->children.back(),
- t_param_names, std::placeholders::_1, std::map()), static_cast(numparams), this->children.back(),
- param_types, l_annotation, guard), type), function_name);
- } catch (const std::range_error &) {
- param_types.push_front(class_name, Type_Info());
- // Do not know type name
- t_ss.add(
- std::make_shared(class_name,
- std::make_shared(std::bind(chaiscript::eval::detail::eval_function,
- std::ref(t_ss), this->children.back(),
- t_param_names, std::placeholders::_1, std::map()), static_cast(numparams), this->children.back(),
- param_types, l_annotation, guard)), function_name);
- }
+ // if the type is unknown, then this generates a function that looks up the type
+ // at runtime. Defining the type first before this is called is better
+ auto type = t_ss.get_type(class_name, false);
+ param_types.push_front(class_name, type);
+
+ t_ss.add(
+ std::make_shared(class_name,
+ std::make_shared(std::bind(chaiscript::eval::detail::eval_function,
+ std::ref(t_ss), this->children.back(),
+ t_param_names, std::placeholders::_1, std::map()), static_cast(numparams), this->children.back(),
+ param_types, l_annotation, guard), type), function_name);
}
}
catch (const exception::reserved_word_error &e) {
diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp
index 8e5bc0d..73a33e2 100644
--- a/include/chaiscript/language/chaiscript_parser.hpp
+++ b/include/chaiscript/language/chaiscript_parser.hpp
@@ -617,14 +617,16 @@ namespace chaiscript
}
- size_t size = sizeof(int) * 8;
-
- if (longlong_)
- {
- size = sizeof(int64_t) * 8;
- } else if (long_) {
- size = sizeof(long) * 8;
- }
+ const size_t size = [&](){
+ if (longlong_)
+ {
+ return sizeof(int64_t) * 8;
+ } else if (long_) {
+ return sizeof(long) * 8;
+ } else {
+ return sizeof(int) * 8;
+ }
+ }();
if ( (u >> (size - 1)) > 0)
{
@@ -794,17 +796,19 @@ namespace chaiscript
return Id_();
} else {
const auto start = m_input_pos;
- const int prev_col = m_col;
- const int prev_line = m_line;
+ const auto prev_col = m_col;
+ const auto prev_line = m_line;
if (Id_()) {
- std::string match;
- if (*start == '`') {
- //Id Literal
- match = std::string(start+1, m_input_pos-1);
- } else {
- match = std::string(start, m_input_pos);
- }
- m_match_stack.push_back(std::make_shared(std::move(match), m_filename, prev_line, prev_col, m_line, m_col));
+ m_match_stack.push_back(std::make_shared(
+ [&](){
+ if (*start == '`') {
+ //Id Literal
+ return std::string(start+1, m_input_pos-1);
+ } else {
+ return std::string(start, m_input_pos);
+ }
+ }(),
+ m_filename, prev_line, prev_col, m_line, m_col));
return true;
} else {
return false;
@@ -1114,8 +1118,8 @@ namespace chaiscript
const auto prev_col = m_col;
const auto prev_line = m_line;
if (Char_(t_c)) {
- std::string match(start, m_input_pos);
- m_match_stack.push_back(std::make_shared(std::move(match), m_filename, prev_line, prev_col, m_line, m_col));
+ m_match_stack.push_back(
+ std::make_shared(std::string(start, m_input_pos), m_filename, prev_line, prev_col, m_line, m_col));
return true;
} else {
return false;
@@ -1159,8 +1163,8 @@ namespace chaiscript
}
if ( t_capture && retval ) {
- std::string match(start, m_input_pos);
- m_match_stack.push_back(std::make_shared(std::move(match), m_filename, prev_line, prev_col, m_line, m_col));
+ m_match_stack.push_back(std::make_shared(
+ std::string(start, m_input_pos), m_filename, prev_line, prev_col, m_line, m_col));
}
return retval;
}
@@ -1202,8 +1206,8 @@ namespace chaiscript
}
if ( t_capture && retval ) {
- std::string match(start, m_input_pos);
- m_match_stack.push_back(std::make_shared(std::move(match), m_filename, prev_line, prev_col, m_line, m_col));
+ m_match_stack.push_back(std::make_shared(
+ std::string(start, m_input_pos), m_filename, prev_line, prev_col, m_line, m_col));
}
return retval;
@@ -1235,8 +1239,8 @@ namespace chaiscript
const auto prev_col = m_col;
const auto prev_line = m_line;
if (Eol_()) {
- std::string match(start, m_input_pos);
- m_match_stack.push_back(std::make_shared(std::move(match), m_filename, prev_line, prev_col, m_line, m_col));
+ m_match_stack.push_back(std::make_shared(
+ std::string(start, m_input_pos), m_filename, prev_line, prev_col, m_line, m_col));
return true;
} else {
return false;
diff --git a/unittests/eval.chai b/unittests/eval.chai
index 2f18aa4..4db72da 100644
--- a/unittests/eval.chai
+++ b/unittests/eval.chai
@@ -1 +1,3 @@
assert_equal(7, eval("3 + 4"))
+
+
diff --git a/unittests/eval_file.chai b/unittests/eval_file.chai
new file mode 100644
index 0000000..be9934e
--- /dev/null
+++ b/unittests/eval_file.chai
@@ -0,0 +1,10 @@
+
+try {
+ eval_file("use.inc")
+ assert(true)
+
+ //we expect this second eval_file to fail because of a function redefinition
+ eval_file("use.inc")
+ assert(false)
+} catch (e) {
+}
diff --git a/unittests/use.chai b/unittests/use.chai
index efd587d..317cced 100644
--- a/unittests/use.chai
+++ b/unittests/use.chai
@@ -1,4 +1,5 @@
-use("use.inc")
+var newfun = use("use.inc");
+
assert_equal("hello", greet())
@@ -7,3 +8,4 @@ use("use.inc")
assert_equal("hello", greet())
+assert_equal("world", newfun())
diff --git a/unittests/use.inc b/unittests/use.inc
index 2897093..0f9fea7 100644
--- a/unittests/use.inc
+++ b/unittests/use.inc
@@ -2,3 +2,4 @@ def greet {
return("hello")
}
+fun(){ "world" }
diff --git a/unittests/vector_access.chai b/unittests/vector_access.chai
index 58269a2..48ca8bd 100644
--- a/unittests/vector_access.chai
+++ b/unittests/vector_access.chai
@@ -1,2 +1,10 @@
auto x = [1, 2, 3]
assert_equal(3, x[2])
+
+
+for (auto i = x.size()-1; i > 0; --i)
+{
+ print("Index: " + to_string(i))
+ print(x[i]);
+ x[i] = 23;
+}