diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..d0c095e1 --- /dev/null +++ b/.clang-format @@ -0,0 +1,98 @@ +AccessModifierOffset: -2 +AlignAfterOpenBracket: DontAlign +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: false +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterClass: true + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyNamespace: true + SplitEmptyRecord: true +BreakAfterJavaFieldAnnotations: true +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: true +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakConstructorInitializersBeforeComma: false +BreakStringLiterals: true +ColumnLimit: 0 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: false +DerivePointerAlignment: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: true +FixNamespaceComments: true +ForEachMacros: +- foreach +- Q_FOREACH +- BOOST_FOREACH +IncludeCategories: +- Priority: 2 + Regex: ^"(llvm|llvm-c|clang|clang-c)/ +- Priority: 3 + Regex: ^(<|"(gtest|gmock|isl|json)/) +- Priority: 1 + Regex: .* +IncludeIsMainRegex: (Test)?$ +IndentCaseLabels: false +IndentWidth: 2 +IndentWrappedFunctionNames: true +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +Language: Cpp +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: Inner +ObjCBlockIndentWidth: 7 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: false +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 0 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: true +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 8 +UseTab: Never + diff --git a/cheatsheet.md b/cheatsheet.md index 28debbca..266ddc71 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -5,7 +5,7 @@ ChaiScript tries to follow the [Semantic Versioning](http://semver.org/) scheme. * Major Version Number: API changes / breaking changes * Minor Version Number: New Features * Patch Version Number: Minor changes / enhancements - + # Initializing ChaiScript @@ -37,7 +37,7 @@ chai.add(chaiscript::fun(&Class::method_name, Class_instance_ptr), "method_name" chai.add(chaiscript::fun(&Class::member_name, Class_instance_ptr), "member_name"); ``` -### With Overloads +### With Overloads #### Preferred @@ -69,9 +69,9 @@ chai.add(chaiscript::fun(static_cast(&Derived::data)), "data"); ``` chai.add( chaiscript::fun( - [](bool type) { - if (type) { return "x"; } - else { return "y"; } + [](bool type) { + if (type) { return "x"; } + else { return "y"; } }), "function_name"); ``` @@ -168,7 +168,7 @@ chai.set_global(chaiscript::var(somevar), "somevar"); // global non-const, overw ## Adding Namespaces -Namespaces will not be populated until `import` is called. +Namespaces will not be populated until `import` is called. This saves memory and computing costs if a namespace is not imported into every ChaiScript instance. ``` chai.register_namespace([](chaiscript::Namespace& math) { diff --git a/contrib/vim b/contrib/vim new file mode 100644 index 00000000..0877d674 --- /dev/null +++ b/contrib/vim @@ -0,0 +1 @@ +vim support can be found at https://github.com/ChaiScript/vim-chaiscript diff --git a/contrib/vim/README.txt b/contrib/vim/README.txt deleted file mode 100644 index a79b1e75..00000000 --- a/contrib/vim/README.txt +++ /dev/null @@ -1,7 +0,0 @@ -Install ftdetect, indent and syntax subdirectories to: - -~/.vim/ - -See the vim documentation on this: - -http://vimdoc.sourceforge.net/htmldoc/syntax.html#mysyntaxfile diff --git a/contrib/vim/ftdetect/chaiscript.vim b/contrib/vim/ftdetect/chaiscript.vim deleted file mode 100644 index c4ce5ef2..00000000 --- a/contrib/vim/ftdetect/chaiscript.vim +++ /dev/null @@ -1,2 +0,0 @@ -au BufRead,BufNewFile *.chai set filetype=chaiscript - diff --git a/contrib/vim/indent/chaiscript.vim b/contrib/vim/indent/chaiscript.vim deleted file mode 100644 index 247e1a6e..00000000 --- a/contrib/vim/indent/chaiscript.vim +++ /dev/null @@ -1,50 +0,0 @@ -" Vim indent file -" Language: ChaiScript -" Maintainer: Jason Turner - -" Only load this indent file when no other was loaded. -if exists("b:did_indent") - finish -endif -let b:did_indent = 1 - -setlocal indentexpr=GetChaiScriptIndent() -setlocal autoindent - -" Only define the function once. -if exists("*GetChaiScriptIndent") - finish -endif - -function! GetChaiScriptIndent() - " Find a non-blank line above the current line. - let lnum = prevnonblank(v:lnum - 1) - - " Hit the start of the file, use zero indent. - if lnum == 0 - return 0 - endif - - " Add a 'shiftwidth' after lines that start a block: - " lines containing a { - let ind = indent(lnum) - let flag = 0 - let prevline = getline(lnum) - if prevline =~ '^.*{.*' - let ind = ind + &shiftwidth - let flag = 1 - endif - - " Subtract a 'shiftwidth' after lines containing a { followed by a } - " to keep it balanced - if flag == 1 && prevline =~ '.*{.*}.*' - let ind = ind - &shiftwidth - endif - - " Subtract a 'shiftwidth' on lines ending with } - if getline(v:lnum) =~ '^\s*\%(}\)' - let ind = ind - &shiftwidth - endif - - return ind -endfunction diff --git a/contrib/vim/syntax/chaiscript.vim b/contrib/vim/syntax/chaiscript.vim deleted file mode 100644 index b442aaa9..00000000 --- a/contrib/vim/syntax/chaiscript.vim +++ /dev/null @@ -1,99 +0,0 @@ -" Vim syntax file -" Language: ChaiScript -" Maintainer: Jason Turner - -" Quit when a (custom) syntax file was already loaded -if exists("b:current_syntax") - finish -end - -let s:cpo_save = &cpo -set cpo&vim - -syn case match - -" syncing method -syn sync fromstart - -" Strings -syn region chaiscriptString start=+"+ end=+"+ skip=+\\\\\|\\"+ contains=chaiscriptSpecial,chaiscriptEval,@Spell - -" Escape characters -syn match chaiscriptSpecial contained "\\[\\abfnrtv\'\"]\|\\\d\{,3}" - -" String evals -syn region chaiscriptEval contained start="${" end="}" - -" integer number -syn match chaiscriptNumber "\<\d\+\>" - -" floating point number, with dot, optional exponent -syn match chaiscriptFloat "\<\d\+\.\d*\%(e[-+]\=\d\+\)\=\>" - -" floating point number, starting with a dot, optional exponent -syn match chaiscriptFloat "\.\d\+\%(e[-+]\=\d\+\)\=\>" - -" floating point number, without dot, with exponent -syn match chaiscriptFloat "\<\d\+e[-+]\=\d\+\>" - -" Hex strings -syn match chaiscriptNumber "\<0x\x\+\>" - -" Binary strings -syn match chaiscriptNumber "\<0b[01]\+\>" - -" Various language features -syn keyword chaiscriptCond if else -syn keyword chaiscriptRepeat while for do -syn keyword chaiscriptStatement break continue return switch case default -syn keyword chaiscriptExceptions try catch throw - -"Keyword -syn keyword chaiscriptKeyword def true false attr - -"Built in types -syn keyword chaiscriptType fun var auto - -"Built in funcs, keep it simple -syn keyword chaiscriptFunc eval throw - -"Let's treat all backtick operator function lookups as built in too -syn region chaiscriptFunc matchgroup=chaiscriptFunc start="`" end="`" - -" Account for the "[1..10]" syntax, treating it as an operator -" Intentionally leaving out all of the normal, well known operators -syn match chaiscriptOperator "\.\." - -" Guard seperator as an operator -syn match chaiscriptOperator ":" - -" Comments -syn match chaiscriptComment "//.*$" contains=@Spell -syn region chaiscriptComment matchgroup=chaiscriptComment start="/\*" end="\*/" contains=@Spell - - - -hi def link chaiscriptExceptions Exception -hi def link chaiscriptKeyword Keyword -hi def link chaiscriptStatement Statement -hi def link chaiscriptRepeat Repeat -hi def link chaiscriptString String -hi def link chaiscriptNumber Number -hi def link chaiscriptFloat Float -hi def link chaiscriptOperator Operator -hi def link chaiscriptConstant Constant -hi def link chaiscriptCond Conditional -hi def link chaiscriptFunction Function -hi def link chaiscriptComment Comment -hi def link chaiscriptTodo Todo -hi def link chaiscriptError Error -hi def link chaiscriptSpecial SpecialChar -hi def link chaiscriptFunc Identifier -hi def link chaiscriptType Type -hi def link chaiscriptEval Special - -let b:current_syntax = "chaiscript" - -let &cpo = s:cpo_save -unlet s:cpo_save -" vim: nowrap sw=2 sts=2 ts=8 noet diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index f0599e23..1fe3a512 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -168,48 +168,57 @@ namespace chaiscript { } - template - [[nodiscard]] auto parse_num(const std::string_view &t_str) noexcept - -> typename std::enable_if::value, T>::type + + template + auto parse_num(const char *t_str) -> typename std::enable_if::value, T>::type { - T t = 0; - T base = 0; - T decimal_place = 0; - bool exponent = false; - bool neg_exponent = false; + T t = 0; + T base; + T decimal_place = 0; + int exponent = 0; - const auto final_value = [](const T val, const T baseval, const bool hasexp, const bool negexp) -> T { - if (!hasexp) { - return val; - } else { - return baseval * std::pow(T(10), val*T(negexp?-1:1)); - } - }; - - for (const auto c : t_str) { - if (c == '.') { - decimal_place = 10; - } else if (c == 'e' || c == 'E') { - exponent = true; - decimal_place = 0; - base = t; - t = 0; - } else if (c == '-' && exponent) { - neg_exponent = true; - } else if (c == '+' && exponent) { - neg_exponent = false; - } else if (c < '0' || c > '9') { - return final_value(t, base, exponent, neg_exponent); - } else if (decimal_place < T(10)) { - t *= T(10); - t += T(c - '0'); - } else { - t += (T(c - '0') / (T(decimal_place))); - decimal_place *= 10; - } - } - - return final_value(t, base, exponent, neg_exponent); + for (char c;; ++t_str) { + c = *t_str; + switch (c) + { + case '.': + decimal_place = 10; + break; + case 'e': + case 'E': + exponent = 1; + decimal_place = 0; + base = t; + t = 0; + break; + case '-': + exponent = -1; + break; + case '+': + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (decimal_place < 10) { + t *= 10; + t += c - '0'; + } + else { + t += (c - '0') / decimal_place; + decimal_place *= 10; + } + break; + default: + return exponent ? base * std::pow(T(10), t * exponent) : t; + } + } } struct str_equal { diff --git a/include/chaiscript/language/chaiscript_optimizer.hpp b/include/chaiscript/language/chaiscript_optimizer.hpp index e9cdbf04..f8873ba7 100644 --- a/include/chaiscript/language/chaiscript_optimizer.hpp +++ b/include/chaiscript/language/chaiscript_optimizer.hpp @@ -97,7 +97,7 @@ namespace chaiscript { template bool contains_var_decl_in_scope(const eval::AST_Node_Impl &node) noexcept { - if (node.identifier == AST_Node_Type::Var_Decl || node.identifier == AST_Node_Type::Assign_Decl) { + if (node.identifier == AST_Node_Type::Var_Decl || node.identifier == AST_Node_Type::Assign_Decl || node.identifier == AST_Node_Type::Reference) { return true; } @@ -107,6 +107,7 @@ namespace chaiscript { const auto &child = child_at(node, i); if (child.identifier != AST_Node_Type::Block && child.identifier != AST_Node_Type::For + && child.identifier != AST_Node_Type::Ranged_For && contains_var_decl_in_scope(child)) { return true; } @@ -392,21 +393,21 @@ namespace chaiscript { const auto &prefix_node = child_at(*for_node, 2); if (child_count(*for_node) == 4 - && eq_node.identifier == AST_Node_Type::Equation + && eq_node.identifier == AST_Node_Type::Assign_Decl && child_count(eq_node) == 2 - && child_at(eq_node, 0).identifier == AST_Node_Type::Var_Decl + && child_at(eq_node, 0).identifier == AST_Node_Type::Id && child_at(eq_node, 1).identifier == AST_Node_Type::Constant && binary_node.identifier == AST_Node_Type::Binary && binary_node.text == "<" && child_count(binary_node) == 2 && child_at(binary_node, 0).identifier == AST_Node_Type::Id - && child_at(binary_node, 0).text == child_at(child_at(eq_node,0), 0).text + && child_at(binary_node, 0).text == child_at(eq_node,0).text && child_at(binary_node, 1).identifier == AST_Node_Type::Constant && prefix_node.identifier == AST_Node_Type::Prefix && prefix_node.text == "++" && child_count(prefix_node) == 1 && child_at(prefix_node, 0).identifier == AST_Node_Type::Id - && child_at(prefix_node, 0).text == child_at(child_at(eq_node,0), 0).text) + && child_at(prefix_node, 0).text == child_at(eq_node,0).text) { const Boxed_Value &begin = dynamic_cast &>(child_at(eq_node, 1)).m_value; const Boxed_Value &end = dynamic_cast &>(child_at(binary_node, 1)).m_value; diff --git a/unittests/ranged_for.chai b/unittests/ranged_for.chai index 9ef34fed..4e98d7b9 100644 --- a/unittests/ranged_for.chai +++ b/unittests/ranged_for.chai @@ -18,4 +18,9 @@ for (x : retro(range([1,2,3,4]))) { assert_true(result > .6 && result < .7); +var m=["a": ["t": "val"], "b": ["t": "val"]]; +for (i : m) { + var &ref=i.second["t"]; + print(ref); +}