From 59103b5a228d43f7ce572704e033b70096ecdc36 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 29 Mar 2015 21:58:14 -0600 Subject: [PATCH 01/10] Apply some IIFE to reduce copies --- .../dispatchkit/type_conversions.hpp | 41 ++++++++++--------- .../chaiscript/language/chaiscript_parser.hpp | 40 ++++++++++-------- 2 files changed, 43 insertions(+), 38 deletions(-) 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_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 8e5bc0d..e16c452 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; From 88e765bd4ec518cd81c17c54f6e5684abc2848cb Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 1 Apr 2015 08:07:19 -0600 Subject: [PATCH 02/10] Create LICENSE --- LICENSE | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 LICENSE 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. From 8f2e56a681d5066512c09e45b82c21f234d5005b Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 1 Apr 2015 09:47:27 -0600 Subject: [PATCH 03/10] Initial sublime text support --- .../sublimetext/ChaiScript.YAML-tmLanguage | 93 +++++ contrib/sublimetext/ChaiScript.tmLanguage | 333 ++++++++++++++++++ 2 files changed, 426 insertions(+) create mode 100644 contrib/sublimetext/ChaiScript.YAML-tmLanguage create mode 100644 contrib/sublimetext/ChaiScript.tmLanguage 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 + + From 7f1cd29a2cd43bb4f6156a7a90651b3283853923 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 2 Apr 2015 15:40:45 -0600 Subject: [PATCH 04/10] Various cleanups --- .../chaiscript/dispatchkit/dispatchkit.hpp | 16 +++++----- .../dispatchkit/proxy_functions.hpp | 7 +---- .../chaiscript/language/chaiscript_common.hpp | 2 +- .../chaiscript/language/chaiscript_eval.hpp | 30 +++++++++---------- .../chaiscript/language/chaiscript_parser.hpp | 16 +++++----- 5 files changed, 32 insertions(+), 39 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 5e9e4de..cb4233d 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -1007,14 +1007,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)); @@ -1044,6 +1036,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/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index d03c33d..e65b203 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; 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_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 06f2b13..0f7f63a 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); } } } @@ -707,13 +707,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 +729,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 +1172,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); } }; diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index e16c452..73a33e2 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1118,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; @@ -1163,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; } @@ -1206,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; @@ -1239,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; From 9422bc7b2d9dffc55e218a5688a002d313583617 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 6 Apr 2015 06:40:03 -0600 Subject: [PATCH 05/10] Add failing test for size_t vector access --- unittests/vector_access.chai | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/unittests/vector_access.chai b/unittests/vector_access.chai index 58269a2..d9868d7 100644 --- a/unittests/vector_access.chai +++ b/unittests/vector_access.chai @@ -1,2 +1,8 @@ auto x = [1, 2, 3] assert_equal(3, x[2]) + + +for (auto i = x.size() - 1; i >= 0; --i) +{ + print(x[i]); +} From 1557dabf4ff7bad4eb0155d5827996e4b3dd3404 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 6 Apr 2015 07:21:32 -0600 Subject: [PATCH 06/10] Fixes array access with arithmetic conversions Closes #156 --- .../dispatchkit/proxy_functions.hpp | 20 +++++++++++-------- unittests/vector_access.chai | 4 +++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index e65b203..1f71ad5 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -717,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)); + } } } @@ -803,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/unittests/vector_access.chai b/unittests/vector_access.chai index d9868d7..48ca8bd 100644 --- a/unittests/vector_access.chai +++ b/unittests/vector_access.chai @@ -2,7 +2,9 @@ auto x = [1, 2, 3] assert_equal(3, x[2]) -for (auto i = x.size() - 1; i >= 0; --i) +for (auto i = x.size()-1; i > 0; --i) { + print("Index: " + to_string(i)) print(x[i]); + x[i] = 23; } From 962bdf4b3c8d566058784e6dcbd9b172c9c48c01 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 6 Apr 2015 13:17:41 -0600 Subject: [PATCH 07/10] Reduce exceptions on startup to minimum This still has some exceptions thrown during the loading of modules since I have no way of knowing where the operating system `dlopen` and `LoadLibrary` functions will search for me to pre-check it. Closes #158 --- include/chaiscript/dispatchkit/bootstrap.hpp | 9 ++-- .../chaiscript/dispatchkit/bootstrap_stl.hpp | 3 +- .../chaiscript/dispatchkit/dispatchkit.hpp | 16 +++++++- .../dispatchkit/dynamic_object_detail.hpp | 2 +- .../chaiscript/language/chaiscript_engine.hpp | 4 +- .../chaiscript/language/chaiscript_eval.hpp | 41 ++++++------------- 6 files changed, 39 insertions(+), 36 deletions(-) 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/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index cb4233d..46155ca 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 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/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index a266bc6..b4e5269 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -353,7 +353,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)); } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 0f7f63a..0b1c564 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -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)); } } @@ -1484,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) { From 79181fe41ef0e01fc215f12a0ee178f711019e70 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 7 Apr 2015 10:23:43 -0600 Subject: [PATCH 08/10] Reduce copies of UDTs --- include/chaiscript/chaiscript_threading.hpp | 3 +++ .../dispatchkit/boxed_cast_helper.hpp | 22 +++++-------------- .../chaiscript/dispatchkit/handle_return.hpp | 17 +++++++++----- 3 files changed, 20 insertions(+), 22 deletions(-) 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/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index a71c7cd..69cfc7c 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(); } } }; @@ -91,11 +81,11 @@ namespace chaiscript typedef Result * Result_Type; static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) { - if (ob.is_ref()) + if (!ob.get_type_info().is_const() && ob.get_type_info().bare_equal_type_info(typeid(Result))) { - return &(ob.get().cast >()).get(); + return static_cast(throw_if_null(ob.get_ptr())); } else { - return (ob.get().cast >()).get(); + throw chaiscript::detail::exception::bad_any_cast(); } } }; 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 From 5114ca9d357f3387d1d8376f53c76825cfe246ff Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 7 Apr 2015 11:09:47 -0600 Subject: [PATCH 09/10] Fix double pointer cast test --- include/chaiscript/dispatchkit/boxed_cast_helper.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index 69cfc7c..c218d30 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -81,16 +81,17 @@ namespace chaiscript typedef Result * Result_Type; static Result_Type cast(const Boxed_Value &ob, const Type_Conversions *) { - if (!ob.get_type_info().is_const() && ob.get_type_info().bare_equal_type_info(typeid(Result))) + if (ob.is_ref()) { - return static_cast(throw_if_null(ob.get_ptr())); + return &(ob.get().cast >()).get(); } else { - throw chaiscript::detail::exception::bad_any_cast(); + return (ob.get().cast >()).get(); } } }; + /// Cast_Helper_Inner for casting to a & type template struct Cast_Helper_Inner From 63684d00425ffea5c5c30ad3bf546bc01a3d0dd3 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 8 Apr 2015 08:17:33 -0600 Subject: [PATCH 10/10] Add the ability to get the return value from 'use' --- cheatsheet.md | 11 ++++++++++ .../chaiscript/language/chaiscript_engine.hpp | 22 ++++++++++++++----- unittests/eval.chai | 2 ++ unittests/eval_file.chai | 10 +++++++++ unittests/use.chai | 4 +++- unittests/use.inc | 1 + 6 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 unittests/eval_file.chai 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/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index b4e5269..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 @@ -369,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"); @@ -457,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; }; @@ -531,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) { @@ -541,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/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" }