diff --git a/.gitignore b/.gitignore index 90d94706..c0ab5df0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ benchmark/ lib/linguist/samples.json /grammars /node_modules +test/fixtures/ace_modes.json +/vendor/gems/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..7c071b85 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,620 @@ +[submodule "vendor/grammars/go-tmbundle"] + path = vendor/grammars/go-tmbundle + url = https://github.com/AlanQuatermain/go-tmbundle +[submodule "vendor/grammars/PHP-Twig.tmbundle"] + path = vendor/grammars/PHP-Twig.tmbundle + url = https://github.com/Anomareh/PHP-Twig.tmbundle +[submodule "vendor/grammars/sublime-cirru"] + path = vendor/grammars/sublime-cirru + url = https://github.com/Cirru/sublime-cirru +[submodule "vendor/grammars/Sublime-Logos"] + path = vendor/grammars/Sublime-Logos + url = https://github.com/Cykey/Sublime-Logos +[submodule "vendor/grammars/SublimeBrainfuck"] + path = vendor/grammars/SublimeBrainfuck + url = https://github.com/Drako/SublimeBrainfuck +[submodule "vendor/grammars/awk-sublime"] + path = vendor/grammars/awk-sublime + url = https://github.com/JohnNilsson/awk-sublime +[submodule "vendor/grammars/Sublime-SQF-Language"] + path = vendor/grammars/Sublime-SQF-Language + url = https://github.com/JonBons/Sublime-SQF-Language +[submodule "vendor/grammars/SCSS.tmbundle"] + path = vendor/grammars/SCSS.tmbundle + url = https://github.com/MarioRicalde/SCSS.tmbundle +[submodule "vendor/grammars/Sublime-REBOL"] + path = vendor/grammars/Sublime-REBOL + url = https://github.com/Oldes/Sublime-REBOL +[submodule "vendor/grammars/Sublime-Inform"] + path = vendor/grammars/Sublime-Inform + url = https://github.com/PogiNate/Sublime-Inform +[submodule "vendor/grammars/autoitv3-tmbundle"] + path = vendor/grammars/autoitv3-tmbundle + url = https://github.com/Red-Nova-Technologies/autoitv3-tmbundle +[submodule "vendor/grammars/Sublime-VimL"] + path = vendor/grammars/Sublime-VimL + url = https://github.com/SalGnt/Sublime-VimL +[submodule "vendor/grammars/boo-sublime"] + path = vendor/grammars/boo-sublime + url = https://github.com/Shammah/boo-sublime +[submodule "vendor/grammars/ColdFusion"] + path = vendor/grammars/ColdFusion + url = https://github.com/SublimeText/ColdFusion +[submodule "vendor/grammars/NSIS"] + path = vendor/grammars/NSIS + url = https://github.com/SublimeText/NSIS +[submodule "vendor/grammars/NimLime"] + path = vendor/grammars/NimLime + url = https://github.com/Varriount/NimLime +[submodule "vendor/grammars/gradle.tmbundle"] + path = vendor/grammars/gradle.tmbundle + url = https://github.com/alkemist/gradle.tmbundle +[submodule "vendor/grammars/Sublime-Loom"] + path = vendor/grammars/Sublime-Loom + url = https://github.com/ambethia/Sublime-Loom +[submodule "vendor/grammars/VBDotNetSyntax"] + path = vendor/grammars/VBDotNetSyntax + url = https://github.com/angryant0007/VBDotNetSyntax +[submodule "vendor/grammars/cool-tmbundle"] + path = vendor/grammars/cool-tmbundle + url = https://github.com/anunayk/cool-tmbundle +[submodule "vendor/grammars/Docker.tmbundle"] + path = vendor/grammars/Docker.tmbundle + url = https://github.com/asbjornenge/Docker.tmbundle +[submodule "vendor/grammars/jasmin-sublime"] + path = vendor/grammars/jasmin-sublime + url = https://github.com/atmarksharp/jasmin-sublime +[submodule "vendor/grammars/language-clojure"] + path = vendor/grammars/language-clojure + url = https://github.com/atom/language-clojure +[submodule "vendor/grammars/language-coffee-script"] + path = vendor/grammars/language-coffee-script + url = https://github.com/atom/language-coffee-script +[submodule "vendor/grammars/language-csharp"] + path = vendor/grammars/language-csharp + url = https://github.com/atom/language-csharp +[submodule "vendor/grammars/language-gfm"] + path = vendor/grammars/language-gfm + url = https://github.com/atom/language-gfm +[submodule "vendor/grammars/language-javascript"] + path = vendor/grammars/language-javascript + url = https://github.com/atom/language-javascript +[submodule "vendor/grammars/language-python"] + path = vendor/grammars/language-python + url = https://github.com/atom/language-python +[submodule "vendor/grammars/language-shellscript"] + path = vendor/grammars/language-shellscript + url = https://github.com/atom/language-shellscript +[submodule "vendor/grammars/language-yaml"] + path = vendor/grammars/language-yaml + url = https://github.com/atom/language-yaml +[submodule "vendor/grammars/sublime-sourcepawn"] + path = vendor/grammars/sublime-sourcepawn + url = https://github.com/austinwagner/sublime-sourcepawn +[submodule "vendor/grammars/Sublime-Lasso"] + path = vendor/grammars/Sublime-Lasso + url = https://github.com/bfad/Sublime-Lasso +[submodule "vendor/grammars/chapel-tmbundle"] + path = vendor/grammars/chapel-tmbundle + url = https://github.com/bholt/chapel-tmbundle +[submodule "vendor/grammars/sublime-nginx"] + path = vendor/grammars/sublime-nginx + url = https://github.com/brandonwamboldt/sublime-nginx +[submodule "vendor/grammars/bro-sublime"] + path = vendor/grammars/bro-sublime + url = https://github.com/bro/bro-sublime +[submodule "vendor/grammars/sublime_man_page_support"] + path = vendor/grammars/sublime_man_page_support + url = https://github.com/carsonoid/sublime_man_page_support +[submodule "vendor/grammars/sublime-MuPAD"] + path = vendor/grammars/sublime-MuPAD + url = https://github.com/ccreutzig/sublime-MuPAD +[submodule "vendor/grammars/nesC.tmbundle"] + path = vendor/grammars/nesC.tmbundle + url = https://github.com/cdwilson/nesC.tmbundle +[submodule "vendor/grammars/haxe-sublime-bundle"] + path = vendor/grammars/haxe-sublime-bundle + url = https://github.com/clemos/haxe-sublime-bundle +[submodule "vendor/grammars/cucumber-tmbundle"] + path = vendor/grammars/cucumber-tmbundle + url = https://github.com/cucumber/cucumber-tmbundle +[submodule "vendor/grammars/Handlebars"] + path = vendor/grammars/Handlebars + url = https://github.com/daaain/Handlebars +[submodule "vendor/grammars/powershell"] + path = vendor/grammars/powershell + url = https://github.com/SublimeText/PowerShell +[submodule "vendor/grammars/jade-tmbundle"] + path = vendor/grammars/jade-tmbundle + url = https://github.com/davidrios/jade-tmbundle +[submodule "vendor/grammars/elixir-tmbundle"] + path = vendor/grammars/elixir-tmbundle + url = https://github.com/elixir-lang/elixir-tmbundle +[submodule "vendor/grammars/sublime-glsl"] + path = vendor/grammars/sublime-glsl + url = https://github.com/euler0/sublime-glsl +[submodule "vendor/grammars/fancy-tmbundle"] + path = vendor/grammars/fancy-tmbundle + url = https://github.com/fancy-lang/fancy-tmbundle +[submodule "vendor/grammars/fsharpbinding"] + path = vendor/grammars/fsharpbinding + url = https://github.com/fsharp/fsharpbinding +[submodule "vendor/grammars/monkey.tmbundle"] + path = vendor/grammars/monkey.tmbundle + url = https://github.com/gingerbeardman/monkey.tmbundle +[submodule "vendor/grammars/dart-sublime-bundle"] + path = vendor/grammars/dart-sublime-bundle + url = https://github.com/guillermooo/dart-sublime-bundle +[submodule "vendor/grammars/sublimetext-cuda-cpp"] + path = vendor/grammars/sublimetext-cuda-cpp + url = https://github.com/harrism/sublimetext-cuda-cpp +[submodule "vendor/grammars/pike-textmate"] + path = vendor/grammars/pike-textmate + url = https://github.com/hww3/pike-textmate +[submodule "vendor/grammars/ceylon-sublimetext"] + path = vendor/grammars/ceylon-sublimetext + url = https://github.com/jeancharles-roger/ceylon-sublimetext +[submodule "vendor/grammars/Sublime-Text-2-OpenEdge-ABL"] + path = vendor/grammars/Sublime-Text-2-OpenEdge-ABL + url = https://github.com/jfairbank/Sublime-Text-2-OpenEdge-ABL +[submodule "vendor/grammars/sublime-rust"] + path = vendor/grammars/sublime-rust + url = https://github.com/jhasse/sublime-rust +[submodule "vendor/grammars/sublime-befunge"] + path = vendor/grammars/sublime-befunge + url = https://github.com/johanasplund/sublime-befunge +[submodule "vendor/grammars/RDoc.tmbundle"] + path = vendor/grammars/RDoc.tmbundle + url = https://github.com/joshaven/RDoc.tmbundle +[submodule "vendor/grammars/Textmate-Gosu-Bundle"] + path = vendor/grammars/Textmate-Gosu-Bundle + url = https://github.com/jpcamara/Textmate-Gosu-Bundle +[submodule "vendor/grammars/jquery-tmbundle"] + path = vendor/grammars/jquery-tmbundle + url = https://github.com/kswedberg/jquery-tmbundle +[submodule "vendor/grammars/fish-tmbundle"] + path = vendor/grammars/fish-tmbundle + url = https://github.com/l15n/fish-tmbundle +[submodule "vendor/grammars/sublime-idris"] + path = vendor/grammars/sublime-idris + url = https://github.com/laughedelic/sublime-idris +[submodule "vendor/grammars/sublime-better-typescript"] + path = vendor/grammars/sublime-better-typescript + url = https://github.com/lavrton/sublime-better-typescript +[submodule "vendor/grammars/moonscript-tmbundle"] + path = vendor/grammars/moonscript-tmbundle + url = https://github.com/leafo/moonscript-tmbundle +[submodule "vendor/grammars/Isabelle.tmbundle"] + path = vendor/grammars/Isabelle.tmbundle + url = https://github.com/lsf37/Isabelle.tmbundle +[submodule "vendor/grammars/x86-assembly-textmate-bundle"] + path = vendor/grammars/x86-assembly-textmate-bundle + url = https://github.com/lunixbochs/x86-assembly-textmate-bundle +[submodule "vendor/grammars/Alloy.tmbundle"] + path = vendor/grammars/Alloy.tmbundle + url = https://github.com/macekond/Alloy.tmbundle +[submodule "vendor/grammars/opa.tmbundle"] + path = vendor/grammars/opa.tmbundle + url = https://github.com/mads379/opa.tmbundle +[submodule "vendor/grammars/scala.tmbundle"] + path = vendor/grammars/scala.tmbundle + url = https://github.com/mads379/scala.tmbundle +[submodule "vendor/grammars/mako-tmbundle"] + path = vendor/grammars/mako-tmbundle + url = https://github.com/marconi/mako-tmbundle +[submodule "vendor/grammars/gnuplot-tmbundle"] + path = vendor/grammars/gnuplot-tmbundle + url = https://github.com/mattfoster/gnuplot-tmbundle +[submodule "vendor/grammars/idl.tmbundle"] + path = vendor/grammars/idl.tmbundle + url = https://github.com/mgalloy/idl.tmbundle +[submodule "vendor/grammars/protobuf-tmbundle"] + path = vendor/grammars/protobuf-tmbundle + url = https://github.com/michaeledgar/protobuf-tmbundle +[submodule "vendor/grammars/Sublime-Coq"] + path = vendor/grammars/Sublime-Coq + url = https://github.com/mkolosick/Sublime-Coq +[submodule "vendor/grammars/Agda.tmbundle"] + path = vendor/grammars/Agda.tmbundle + url = https://github.com/mokus0/Agda.tmbundle +[submodule "vendor/grammars/Julia.tmbundle"] + path = vendor/grammars/Julia.tmbundle + url = https://github.com/nanoant/Julia.tmbundle +[submodule "vendor/grammars/assembly.tmbundle"] + path = vendor/grammars/assembly.tmbundle + url = https://github.com/nanoant/assembly.tmbundle +[submodule "vendor/grammars/ooc.tmbundle"] + path = vendor/grammars/ooc.tmbundle + url = https://github.com/nilium/ooc.tmbundle +[submodule "vendor/grammars/LiveScript.tmbundle"] + path = vendor/grammars/LiveScript.tmbundle + url = https://github.com/paulmillr/LiveScript.tmbundle +[submodule "vendor/grammars/sublime-tea"] + path = vendor/grammars/sublime-tea + url = https://github.com/pferruggiaro/sublime-tea +[submodule "vendor/grammars/puppet-textmate-bundle"] + path = vendor/grammars/puppet-textmate-bundle + url = https://github.com/puppet-textmate-bundle/puppet-textmate-bundle +[submodule "vendor/grammars/abap.tmbundle"] + path = vendor/grammars/abap.tmbundle + url = https://github.com/pvl/abap.tmbundle +[submodule "vendor/grammars/mercury-tmlanguage"] + path = vendor/grammars/mercury-tmlanguage + url = https://github.com/sebgod/mercury-tmlanguage +[submodule "vendor/grammars/mathematica-tmbundle"] + path = vendor/grammars/mathematica-tmbundle + url = https://github.com/shadanan/mathematica-tmbundle +[submodule "vendor/grammars/sublime-robot-plugin"] + path = vendor/grammars/sublime-robot-plugin + url = https://github.com/shellderp/sublime-robot-plugin +[submodule "vendor/grammars/actionscript3-tmbundle"] + path = vendor/grammars/actionscript3-tmbundle + url = https://github.com/honzabrecka/actionscript3-tmbundle +[submodule "vendor/grammars/Sublime-QML"] + path = vendor/grammars/Sublime-QML + url = https://github.com/skozlovf/Sublime-QML +[submodule "vendor/grammars/Slash.tmbundle"] + path = vendor/grammars/Slash.tmbundle + url = https://github.com/slash-lang/Slash.tmbundle +[submodule "vendor/grammars/factor"] + path = vendor/grammars/factor + url = https://github.com/slavapestov/factor +[submodule "vendor/grammars/ruby-slim.tmbundle"] + path = vendor/grammars/ruby-slim.tmbundle + url = https://github.com/slim-template/ruby-slim.tmbundle +[submodule "vendor/grammars/SublimeXtend"] + path = vendor/grammars/SublimeXtend + url = https://github.com/staltz/SublimeXtend +[submodule "vendor/grammars/Stata.tmbundle"] + path = vendor/grammars/Stata.tmbundle + url = https://github.com/statatmbundle/Stata.tmbundle +[submodule "vendor/grammars/Vala-TMBundle"] + path = vendor/grammars/Vala-TMBundle + url = https://github.com/technosophos/Vala-TMBundle +[submodule "vendor/grammars/ant.tmbundle"] + path = vendor/grammars/ant.tmbundle + url = https://github.com/textmate/ant.tmbundle +[submodule "vendor/grammars/antlr.tmbundle"] + path = vendor/grammars/antlr.tmbundle + url = https://github.com/textmate/antlr.tmbundle +[submodule "vendor/grammars/apache.tmbundle"] + path = vendor/grammars/apache.tmbundle + url = https://github.com/textmate/apache.tmbundle +[submodule "vendor/grammars/applescript.tmbundle"] + path = vendor/grammars/applescript.tmbundle + url = https://github.com/textmate/applescript.tmbundle +[submodule "vendor/grammars/asp.tmbundle"] + path = vendor/grammars/asp.tmbundle + url = https://github.com/textmate/asp.tmbundle +[submodule "vendor/grammars/bison.tmbundle"] + path = vendor/grammars/bison.tmbundle + url = https://github.com/textmate/bison.tmbundle +[submodule "vendor/grammars/capnproto.tmbundle"] + path = vendor/grammars/capnproto.tmbundle + url = https://github.com/textmate/capnproto.tmbundle +[submodule "vendor/grammars/cmake.tmbundle"] + path = vendor/grammars/cmake.tmbundle + url = https://github.com/textmate/cmake.tmbundle +[submodule "vendor/grammars/cpp-qt.tmbundle"] + path = vendor/grammars/cpp-qt.tmbundle + url = https://github.com/textmate/cpp-qt.tmbundle +[submodule "vendor/grammars/css.tmbundle"] + path = vendor/grammars/css.tmbundle + url = https://github.com/textmate/css.tmbundle +[submodule "vendor/grammars/d.tmbundle"] + path = vendor/grammars/d.tmbundle + url = https://github.com/textmate/d.tmbundle +[submodule "vendor/grammars/diff.tmbundle"] + path = vendor/grammars/diff.tmbundle + url = https://github.com/textmate/diff.tmbundle +[submodule "vendor/grammars/dylan.tmbundle"] + path = vendor/grammars/dylan.tmbundle + url = https://github.com/textmate/dylan.tmbundle +[submodule "vendor/grammars/eiffel.tmbundle"] + path = vendor/grammars/eiffel.tmbundle + url = https://github.com/textmate/eiffel.tmbundle +[submodule "vendor/grammars/erlang.tmbundle"] + path = vendor/grammars/erlang.tmbundle + url = https://github.com/textmate/erlang.tmbundle +[submodule "vendor/grammars/fortran.tmbundle"] + path = vendor/grammars/fortran.tmbundle + url = https://github.com/textmate/fortran.tmbundle +[submodule "vendor/grammars/gettext.tmbundle"] + path = vendor/grammars/gettext.tmbundle + url = https://github.com/textmate/gettext.tmbundle +[submodule "vendor/grammars/graphviz.tmbundle"] + path = vendor/grammars/graphviz.tmbundle + url = https://github.com/textmate/graphviz.tmbundle +[submodule "vendor/grammars/groovy.tmbundle"] + path = vendor/grammars/groovy.tmbundle + url = https://github.com/textmate/groovy.tmbundle +[submodule "vendor/grammars/haskell.tmbundle"] + path = vendor/grammars/haskell.tmbundle + url = https://github.com/textmate/haskell.tmbundle +[submodule "vendor/grammars/html.tmbundle"] + path = vendor/grammars/html.tmbundle + url = https://github.com/textmate/html.tmbundle +[submodule "vendor/grammars/ini.tmbundle"] + path = vendor/grammars/ini.tmbundle + url = https://github.com/textmate/ini.tmbundle +[submodule "vendor/grammars/desktop.tmbundle"] + path = vendor/grammars/desktop.tmbundle + url = https://github.com/Mailaender/desktop.tmbundle.git +[submodule "vendor/grammars/io.tmbundle"] + path = vendor/grammars/io.tmbundle + url = https://github.com/textmate/io.tmbundle +[submodule "vendor/grammars/java.tmbundle"] + path = vendor/grammars/java.tmbundle + url = https://github.com/textmate/java.tmbundle +[submodule "vendor/grammars/javadoc.tmbundle"] + path = vendor/grammars/javadoc.tmbundle + url = https://github.com/textmate/javadoc.tmbundle +[submodule "vendor/grammars/javascript-objective-j.tmbundle"] + path = vendor/grammars/javascript-objective-j.tmbundle + url = https://github.com/textmate/javascript-objective-j.tmbundle +[submodule "vendor/grammars/json.tmbundle"] + path = vendor/grammars/json.tmbundle + url = https://github.com/textmate/json.tmbundle +[submodule "vendor/grammars/latex.tmbundle"] + path = vendor/grammars/latex.tmbundle + url = https://github.com/textmate/latex.tmbundle +[submodule "vendor/grammars/less.tmbundle"] + path = vendor/grammars/less.tmbundle + url = https://github.com/textmate/less.tmbundle +[submodule "vendor/grammars/lilypond.tmbundle"] + path = vendor/grammars/lilypond.tmbundle + url = https://github.com/textmate/lilypond.tmbundle +[submodule "vendor/grammars/lisp.tmbundle"] + path = vendor/grammars/lisp.tmbundle + url = https://github.com/textmate/lisp.tmbundle +[submodule "vendor/grammars/logtalk.tmbundle"] + path = vendor/grammars/logtalk.tmbundle + url = https://github.com/textmate/logtalk.tmbundle +[submodule "vendor/grammars/lua.tmbundle"] + path = vendor/grammars/lua.tmbundle + url = https://github.com/textmate/lua.tmbundle +[submodule "vendor/grammars/make.tmbundle"] + path = vendor/grammars/make.tmbundle + url = https://github.com/textmate/make.tmbundle +[submodule "vendor/grammars/matlab.tmbundle"] + path = vendor/grammars/matlab.tmbundle + url = https://github.com/textmate/matlab.tmbundle +[submodule "vendor/grammars/maven.tmbundle"] + path = vendor/grammars/maven.tmbundle + url = https://github.com/textmate/maven.tmbundle +[submodule "vendor/grammars/nemerle.tmbundle"] + path = vendor/grammars/nemerle.tmbundle + url = https://github.com/textmate/nemerle.tmbundle +[submodule "vendor/grammars/ninja.tmbundle"] + path = vendor/grammars/ninja.tmbundle + url = https://github.com/textmate/ninja.tmbundle +[submodule "vendor/grammars/objective-c.tmbundle"] + path = vendor/grammars/objective-c.tmbundle + url = https://github.com/textmate/objective-c.tmbundle +[submodule "vendor/grammars/ocaml.tmbundle"] + path = vendor/grammars/ocaml.tmbundle + url = https://github.com/textmate/ocaml.tmbundle +[submodule "vendor/grammars/pascal.tmbundle"] + path = vendor/grammars/pascal.tmbundle + url = https://github.com/textmate/pascal.tmbundle +[submodule "vendor/grammars/perl.tmbundle"] + path = vendor/grammars/perl.tmbundle + url = https://github.com/textmate/perl.tmbundle +[submodule "vendor/grammars/php-smarty.tmbundle"] + path = vendor/grammars/php-smarty.tmbundle + url = https://github.com/textmate/php-smarty.tmbundle +[submodule "vendor/grammars/php.tmbundle"] + path = vendor/grammars/php.tmbundle + url = https://github.com/textmate/php.tmbundle +[submodule "vendor/grammars/postscript.tmbundle"] + path = vendor/grammars/postscript.tmbundle + url = https://github.com/textmate/postscript.tmbundle +[submodule "vendor/grammars/processing.tmbundle"] + path = vendor/grammars/processing.tmbundle + url = https://github.com/textmate/processing.tmbundle +[submodule "vendor/grammars/prolog.tmbundle"] + path = vendor/grammars/prolog.tmbundle + url = https://github.com/textmate/prolog.tmbundle +[submodule "vendor/grammars/python-django.tmbundle"] + path = vendor/grammars/python-django.tmbundle + url = https://github.com/textmate/python-django.tmbundle +[submodule "vendor/grammars/r.tmbundle"] + path = vendor/grammars/r.tmbundle + url = https://github.com/textmate/r.tmbundle +[submodule "vendor/grammars/restructuredtext.tmbundle"] + path = vendor/grammars/restructuredtext.tmbundle + url = https://github.com/textmate/restructuredtext.tmbundle +[submodule "vendor/grammars/ruby-haml.tmbundle"] + path = vendor/grammars/ruby-haml.tmbundle + url = https://github.com/textmate/ruby-haml.tmbundle +[submodule "vendor/grammars/ruby-on-rails-tmbundle"] + path = vendor/grammars/ruby-on-rails-tmbundle + url = https://github.com/textmate/ruby-on-rails-tmbundle +[submodule "vendor/grammars/scheme.tmbundle"] + path = vendor/grammars/scheme.tmbundle + url = https://github.com/textmate/scheme.tmbundle +[submodule "vendor/grammars/scilab.tmbundle"] + path = vendor/grammars/scilab.tmbundle + url = https://github.com/textmate/scilab.tmbundle +[submodule "vendor/grammars/sql.tmbundle"] + path = vendor/grammars/sql.tmbundle + url = https://github.com/textmate/sql.tmbundle +[submodule "vendor/grammars/standard-ml.tmbundle"] + path = vendor/grammars/standard-ml.tmbundle + url = https://github.com/textmate/standard-ml.tmbundle +[submodule "vendor/grammars/swift.tmbundle"] + path = vendor/grammars/swift.tmbundle + url = https://github.com/textmate/swift.tmbundle +[submodule "vendor/grammars/tcl.tmbundle"] + path = vendor/grammars/tcl.tmbundle + url = https://github.com/textmate/tcl.tmbundle +[submodule "vendor/grammars/text.tmbundle"] + path = vendor/grammars/text.tmbundle + url = https://github.com/textmate/text.tmbundle +[submodule "vendor/grammars/textile.tmbundle"] + path = vendor/grammars/textile.tmbundle + url = https://github.com/textmate/textile.tmbundle +[submodule "vendor/grammars/textmate.tmbundle"] + path = vendor/grammars/textmate.tmbundle + url = https://github.com/textmate/textmate.tmbundle +[submodule "vendor/grammars/thrift.tmbundle"] + path = vendor/grammars/thrift.tmbundle + url = https://github.com/textmate/thrift.tmbundle +[submodule "vendor/grammars/toml.tmbundle"] + path = vendor/grammars/toml.tmbundle + url = https://github.com/textmate/toml.tmbundle +[submodule "vendor/grammars/verilog.tmbundle"] + path = vendor/grammars/verilog.tmbundle + url = https://github.com/textmate/verilog.tmbundle +[submodule "vendor/grammars/xml.tmbundle"] + path = vendor/grammars/xml.tmbundle + url = https://github.com/textmate/xml.tmbundle +[submodule "vendor/grammars/smalltalk-tmbundle"] + path = vendor/grammars/smalltalk-tmbundle + url = https://github.com/tomas-stefano/smalltalk-tmbundle +[submodule "vendor/grammars/ioke-outdated"] + path = vendor/grammars/ioke-outdated + url = https://github.com/vic/ioke-outdated +[submodule "vendor/grammars/kotlin-sublime-package"] + path = vendor/grammars/kotlin-sublime-package + url = https://github.com/vkostyukov/kotlin-sublime-package +[submodule "vendor/grammars/c.tmbundle"] + path = vendor/grammars/c.tmbundle + url = https://github.com/textmate/c.tmbundle +[submodule "vendor/grammars/zephir-sublime"] + path = vendor/grammars/zephir-sublime + url = https://github.com/vmg/zephir-sublime +[submodule "vendor/grammars/llvm.tmbundle"] + path = vendor/grammars/llvm.tmbundle + url = https://github.com/whitequark/llvm.tmbundle +[submodule "vendor/grammars/sublime-nix"] + path = vendor/grammars/sublime-nix + url = https://github.com/wmertens/sublime-nix +[submodule "vendor/grammars/ada.tmbundle"] + path = vendor/grammars/ada.tmbundle + url = https://github.com/aroben/ada.tmbundle + branch = better-with-highlighting +[submodule "vendor/grammars/oz-tmbundle"] + path = vendor/grammars/oz-tmbundle + url = https://github.com/eregon/oz-tmbundle +[submodule "vendor/grammars/ebundles"] + path = vendor/grammars/ebundles + url = https://github.com/ericzou/ebundles +[submodule "vendor/grammars/sublime-mask"] + path = vendor/grammars/sublime-mask + url = https://github.com/tenbits/sublime-mask +[submodule "vendor/grammars/sublime_cobol"] + path = vendor/grammars/sublime_cobol + url = https://bitbucket.org/bitlang/sublime_cobol +[submodule "vendor/grammars/ruby.tmbundle"] + path = vendor/grammars/ruby.tmbundle + url = https://github.com/aroben/ruby.tmbundle + branch = pl +[submodule "vendor/grammars/IDL-Syntax"] + path = vendor/grammars/IDL-Syntax + url = https://github.com/andik/IDL-Syntax +[submodule "vendor/grammars/sas.tmbundle"] + path = vendor/grammars/sas.tmbundle + url = https://github.com/rpardee/sas.tmbundle +[submodule "vendor/grammars/atom-salt"] + path = vendor/grammars/atom-salt + url = https://github.com/saltstack/atom-salt +[submodule "vendor/grammars/Scalate.tmbundle"] + path = vendor/grammars/Scalate.tmbundle + url = https://github.com/scalate/Scalate.tmbundle +[submodule "vendor/grammars/Elm.tmLanguage"] + path = vendor/grammars/Elm.tmLanguage + url = https://github.com/deadfoxygrandpa/Elm.tmLanguage +[submodule "vendor/grammars/sublime-bsv"] + path = vendor/grammars/sublime-bsv + url = https://github.com/thotypous/sublime-bsv +[submodule "vendor/grammars/Sublime-HTTP"] + path = vendor/grammars/Sublime-HTTP + url = https://github.com/httpspec/sublime-highlighting +[submodule "vendor/grammars/sass-textmate-bundle"] + path = vendor/grammars/sass-textmate-bundle + url = https://github.com/nathos/sass-textmate-bundle +[submodule "vendor/grammars/carto-atom"] + path = vendor/grammars/carto-atom + url = https://github.com/yohanboniface/carto-atom +[submodule "vendor/grammars/Sublime-Nit"] + path = vendor/grammars/Sublime-Nit + url = https://github.com/R4PaSs/Sublime-Nit +[submodule "vendor/grammars/language-hy"] + path = vendor/grammars/language-hy + url = https://github.com/rwtolbert/language-hy +[submodule "vendor/grammars/Racket"] + path = vendor/grammars/Racket + url = https://github.com/soegaard/racket-highlight-for-github +[submodule "vendor/grammars/turtle.tmbundle"] + path = vendor/grammars/turtle.tmbundle + url = https://github.com/peta/turtle.tmbundle +[submodule "vendor/grammars/liquid.tmbundle"] + path = vendor/grammars/liquid.tmbundle + url = https://github.com/bastilian/validcode-textmate-bundles +[submodule "vendor/grammars/ats.sublime"] + path = vendor/grammars/ats.sublime + url = https://github.com/steinwaywhw/ats-mode-sublimetext +[submodule "vendor/grammars/Modelica"] + path = vendor/grammars/Modelica + url = https://github.com/BorisChumichev/modelicaSublimeTextPackage +[submodule "vendor/grammars/sublime-apl"] + path = vendor/grammars/sublime-apl + url = https://github.com/StoneCypher/sublime-apl +[submodule "vendor/grammars/CLIPS-sublime"] + path = vendor/grammars/CLIPS-sublime + url = https://github.com/psicomante/CLIPS-sublime +[submodule "vendor/grammars/Creole"] + path = vendor/grammars/Creole + url = https://github.com/Siddley/Creole +[submodule "vendor/grammars/GDScript-sublime"] + path = vendor/grammars/GDScript-sublime + url = https://github.com/beefsack/GDScript-sublime +[submodule "vendor/grammars/sublime-golo"] + path = vendor/grammars/sublime-golo + url = https://github.com/TypeUnsafe/sublime-golo +[submodule "vendor/grammars/JSyntax"] + path = vendor/grammars/JSyntax + url = https://github.com/bcj/JSyntax +[submodule "vendor/grammars/TXL"] + path = vendor/grammars/TXL + url = https://github.com/MikeHoffert/Sublime-Text-TXL-syntax +[submodule "vendor/grammars/G-Code"] + path = vendor/grammars/G-Code + url = https://github.com/robotmaster/sublime-text-syntax-highlighting +[submodule "vendor/grammars/grace-tmbundle"] + path = vendor/grammars/grace-tmbundle + url = https://github.com/zmthy/grace-tmbundle +[submodule "vendor/grammars/sublime-text-ox"] + path = vendor/grammars/sublime-text-ox + url = https://github.com/andreashetland/sublime-text-ox +[submodule "vendor/grammars/AutoHotkey"] + path = vendor/grammars/AutoHotkey + url = https://github.com/ahkscript/SublimeAutoHotkey +[submodule "vendor/grammars/ec.tmbundle"] + path = vendor/grammars/ec.tmbundle + url = https://github.com/ecere/ec.tmbundle +[submodule "vendor/grammars/InnoSetup"] + path = vendor/grammars/InnoSetup + url = https://github.com/idleberg/InnoSetup-Sublime-Text +[submodule "vendor/grammars/gap-tmbundle"] + path = vendor/grammars/gap-tmbundle + url = https://github.com/dhowden/gap-tmbundle +[submodule "vendor/grammars/SublimePapyrus"] + path = vendor/grammars/SublimePapyrus + url = https://github.com/Kapiainen/SublimePapyrus +[submodule "vendor/grammars/sublime-spintools"] + path = vendor/grammars/sublime-spintools + url = https://github.com/bitbased/sublime-spintools +[submodule "vendor/grammars/PogoScript.tmbundle"] + path = vendor/grammars/PogoScript.tmbundle + url = https://github.com/featurist/PogoScript.tmbundle +[submodule "vendor/grammars/sublime-opal"] + path = vendor/grammars/sublime-opal + url = https://github.com/artifactz/sublime-opal +[submodule "vendor/grammars/mediawiki.tmbundle"] + path = vendor/grammars/mediawiki.tmbundle + url = https://github.com/textmate/mediawiki.tmbundle +[submodule "vendor/grammars/SublimeClarion"] + path = vendor/grammars/SublimeClarion + url = https://github.com/fushnisoft/SublimeClarion diff --git a/.travis.yml b/.travis.yml index 7b013349..4d0c2351 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,5 @@ -before_install: - - git fetch origin master:master - - git fetch origin v2.0.0:v2.0.0 - - git fetch origin test/attributes:test/attributes - - git fetch origin test/master:test/master - - sudo apt-get install libicu-dev -y +sudo: false +before_install: script/travis/before_install rvm: - 1.9.3 - 2.0.0 @@ -11,3 +7,6 @@ rvm: - 2.2 notifications: disabled: true +git: + submodules: false +cache: bundler diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d0884dab..b1c8a09c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,31 +1,81 @@ -## Contributing +# Contributing -The majority of contributions won't need to touch any Ruby code at all. The [master language list][languages] is just a YAML configuration file. +Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. The majority of contributions won't need to touch any Ruby code at all. -Almost all bug fixes or new language additions should come with some additional code samples. Just drop them under [`samples/`][samples] in the correct subdirectory and our test suite will automatically test them. In most cases you shouldn't need to add any new assertions. +## Adding a language -### My code is detected as the wrong language +We try only to add languages once they have some usage on GitHub. In most cases we prefer that languages be in use in hundreds of repositories before supporting them in Linguist. -This can usually be solved either by adding a new filename or file name extension to the language's entry in [`languages.yml`][languages] or adding more [samples][samples] for your language to the repository to make Linguist's classifier smarter. +To add support for a new language: -### Syntax highlighting looks wrong +0. Add an entry for your language to [`languages.yml`][languages]. +0. Add a grammar for your language. Please only add grammars that have a license that permits redistribution. + 0. Add your grammar as a submodule: `git submodule add https://github.com/JaneSmith/MyGrammar vendor/grammars/MyGrammar`. + 0. Add your grammar to [`grammars.yml`][grammars] by running `script/convert-grammars --add vendor/grammars/MyGrammar`. +0. Add samples for your language to the [samples directory][samples] in the correct subdirectory. +0. Open a pull request, linking to a [GitHub search result](https://github.com/search?utf8=%E2%9C%93&q=extension%3Aboot+NOT+nothack&type=Code&ref=searchresults) showing in-the-wild usage. -Assuming your code is being detected as the right language (see above), in most cases this is due to a bug in the language grammar rather than a bug in Linguist. [`grammars.yml`][grammars] lists all the grammars we use for syntax highlighting on github.com. Find the one corresponding to your code's programming language and submit a bug report upstream. +In addition, if your new language defines an extension that's already listed in [`languages.yml`][languages] (such as `.foo`) then sometimes a few more steps will need to be taken: -You can also try to fix the bug yourself and submit a Pull Request. [This piece from TextMate's documentation](http://manual.macromates.com/en/language_grammars) offers a good introduction on how to work with TextMate-compatible grammars. You can test grammars using [Lightshow](https://lightshow.githubapp.com). +0. Make sure that example `.foo` files are present in the [samples directory][samples] for each language that uses `.foo`. +0. Test the performance of the Bayesian classifier with a relatively large number (1000s) of sample `.foo` files. (ping @arfon or @bkeepers to help with this) to ensure we're not misclassifying files. +0. If the Bayesian classifier does a bad job with the sample `.foo` files then a [heuristic](https://github.com/github/linguist/blob/master/lib/linguist/heuristics.rb) may need to be written to help. + +Remember, the goal here is to try and avoid false positives! + +## Fixing a misclassified language + +Most languages are detected by their file extension defined in [languages.yml][languages]. For disambiguating between files with common extensions, linguist applies some [heuristics](/lib/linguist/heuristics.rb) and a [statistical classifier](lib/linguist/classifier.rb). This process can help differentiate between, for example, `.h` files which could be either C, C++, or Obj-C. + +Misclassifications can often be solved by either adding a new filename or extension for the language or adding more [samples][samples] to make the classifier smarter. + +## Fixing syntax highlighting + +Syntax highlighting in GitHub is performed using TextMate-compatible grammars. These are the same grammars that TextMate, Sublime Text and Atom use. Every language in [languages.yml][languages] is mapped to its corresponding TM `scope`. This scope will be used when picking up a grammar for highlighting. + +Assuming your code is being detected as the right language, in most cases this is due to a bug in the language grammar rather than a bug in Linguist. [`grammars.yml`][grammars] lists all the grammars we use for syntax highlighting on github.com. Find the one corresponding to your code's programming language and submit a bug report upstream. If you can, try to reproduce the highlighting problem in the text editor that the grammar is designed for (TextMate, Sublime Text, or Atom) and include that information in your bug report. + +You can also try to fix the bug yourself and submit a Pull Request. [TextMate's documentation](http://manual.macromates.com/en/language_grammars) offers a good introduction on how to work with TextMate-compatible grammars. You can test grammars using [Lightshow](https://github-lightshow.herokuapp.com). Once the bug has been fixed upstream, please let us know and we'll pick it up for GitHub. -### I want to add support for the `X` programming language +## Testing -Great! You'll need to: +For development you are going to want to checkout out the source. To get it, clone the repo and run [Bundler](http://gembundler.com/) to install its dependencies. -0. Add an entry for your language to [`languages.yml`][languages]. -0. Add a grammar for your language to [`grammars.yml`][grammars] by running `script/download-grammars --add URL`. Please only add grammars that have a license that permits redistribution. -0. Add samples for your language to the [samples directory][samples]. + git clone https://github.com/github/linguist.git + cd linguist/ + script/bootstrap -We try only to add languages once they have some usage on GitHub, so please note in-the-wild usage examples in your pull request. In most cases we prefer that languages already be in use in hundreds of repositories before supporting them in Linguist. +To run the tests: + + bundle exec rake test + +Sometimes getting the tests running can be too much work, especially if you don't have much Ruby experience. It's okay: be lazy and let our build bot [Travis](http://travis-ci.org/#!/github/linguist) run the tests for you. Just open a pull request and the bot will start cranking away. + +Here's our current build status: [![Build Status](https://secure.travis-ci.org/github/linguist.png?branch=master)](http://travis-ci.org/github/linguist) + +## Releasing + +If you are the current maintainer of this gem: + +0. Create a branch for the release: `git checkout -b cut-release-vxx.xx.xx` +0. Make sure your local dependencies are up to date: `script/bootstrap` +0. If grammar submodules have not been updated recently, update them: `git submodule update --remote && git commit -a` +0. Ensure that samples are updated: `bundle exec rake samples` +0. Ensure that tests are green: `bundle exec rake test` +0. Bump gem version in `lib/linguist/version.rb`, [like this](https://github.com/github/linguist/commit/8d2ea90a5ba3b2fe6e1508b7155aa4632eea2985). +0. Make a PR to github/linguist, [like this](https://github.com/github/linguist/pull/1238). +0. Build a local gem: `bundle exec rake build_gem` +0. Test the gem: + 0. Bump the Gemfile and Gemfile.lock versions for an app which relies on this gem + 0. Install the new gem locally + 0. Test behavior locally, branch deploy, whatever needs to happen +0. Merge github/linguist PR +0. Tag and push: `git tag vx.xx.xx; git push --tags` +0. Push to rubygems.org -- `gem push github-linguist-3.0.0.gem` [grammars]: /grammars.yml [languages]: /lib/linguist/languages.yml [samples]: /samples +[new-issue]: https://github.com/github/linguist/issues/new diff --git a/Gemfile b/Gemfile index 95769569..c5f2cc3b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,4 @@ source 'https://rubygems.org' gemspec :name => "github-linguist" gemspec :name => "github-linguist-grammars" -gem 'test-unit', require: false if RUBY_VERSION >= '2.2' gem 'byebug' if RUBY_VERSION >= '2.0' diff --git a/LICENSE b/LICENSE index f09a7d0a..c0a52444 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011-2014 GitHub, Inc. +Copyright (c) 2011-2015 GitHub, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/README.md b/README.md index 5eaa2f20..6a2447a9 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,80 @@ # Linguist -We use this library at GitHub to detect blob languages, ignore binary files, suppress generated files in diffs, and generate language breakdown graphs. +[issues]: https://github.com/github/linguist/issues +[new-issue]: https://github.com/github/linguist/issues/new -Tips for filing issues and creating pull requests can be found in [`CONTRIBUTING.md`](/CONTRIBUTING.md). +This library is used on GitHub.com to detect blob languages, ignore binary or vendored files, suppress generated files in diffs, and generate language breakdown graphs. -## Features +See [Troubleshooting](#troubleshooting) and [`CONTRIBUTING.md`](/CONTRIBUTING.md) before filing an issue or creating a pull request. -### Language detection +## Troubleshooting -Linguist defines a list of all languages known to GitHub in a [yaml file](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml). +### My repository is detected as the wrong language -Most languages are detected by their file extension. For disambiguating between files with common extensions, we first apply some common-sense heuristics to pick out obvious languages. After that, we use a -[statistical -classifier](https://github.com/github/linguist/blob/master/lib/linguist/classifier.rb). -This process can help us tell the difference between, for example, `.h` files which could be either C, C++, or Obj-C. +![language stats bar](https://cloud.githubusercontent.com/assets/173/5562290/48e24654-8ddf-11e4-8fe7-735b0ce3a0d3.png) -```ruby +The Language stats bar is built by aggregating the languages of each file in that repository. If it is reporting a language that you don't expect: -Linguist::FileBlob.new("lib/linguist.rb").language.name #=> "Ruby" +0. Click on the name of the language in the stats bar to see a list of the files that are identified as that language. +0. If you see files that you didn't write, consider moving the files into one of the [paths for vendored code](https://github.com/github/linguist/blob/master/lib/linguist/vendor.yml), or use the [manual overrides](#overrides) feature to ignore them. +0. If the files are being misclassified, search for [open issues][issues] to see if anyone else has already reported the issue. Any information you an add, especially links to public repositories, is helpful. +0. If there are no reported issues of this misclassification, [open an issue][new-issue] and include a link to the repository or a sample of the code that is being misclassified. -Linguist::FileBlob.new("bin/linguist").language.name #=> "Ruby" +## Overrides + +Linguist supports a number of different custom overrides strategies for language definitions and vendored paths. + +### Using gitattributes + +Add a `.gitattributes` file to your project and use standard git-style path matchers for the files you want to override to set `linguist-documentation`, `linguist-language`, and `linguist-vendored`. + +``` +$ cat .gitattributes +*.rb linguist-language=Java ``` -See [lib/linguist/language.rb](https://github.com/github/linguist/blob/master/lib/linguist/language.rb) and [lib/linguist/languages.yml](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml). +Checking code you didn't write, such as JavaScript libraries, into your git repo is a common practice, but this often inflates your project's language stats and may even cause your project to be labeled as another language. By default, Linguist treats all of the paths defined in [lib/linguist/vendor.yml](https://github.com/github/linguist/blob/master/lib/linguist/vendor.yml) as vendored and therefore doesn't include them in the language statistics for a repository. Vendored files are also hidden by default in diffs on github.com. -### Syntax Highlighting +Use the `linguist-vendored` attribute to vendor or un-vendor paths. -Syntax highlighting in GitHub is performed using TextMate-compatible grammars. These are the same grammars that TextMate, Sublime Text and Atom use. +``` +$ cat .gitattributes +special-vendored-path/* linguist-vendored +jquery.js linguist-vendored=false +``` -Every language in `languages.yml` is mapped to its corresponding TM `scope`. This scope will be used when picking up a grammar for highlighting. **When adding a new language to Linguist, please add its corresponding scope too (assuming there's an existing TextMate bundle, Sublime Text package, or Atom package) so syntax highlighting works for it**. +Similar to vendored files, Linguist excludes documentation files from your project's language stats. (Unlike vendored files, documentation files are displayed in diffs on github.com.) [lib/linguist/documentation.yml](lib/linguist/documentation.yml) lists common documentation paths and excludes them from the language statistics for your repository. -### Stats +Use the `linguist-documentation` attribute to mark or unmark paths as documentation. -The Language stats bar that you see on every repository is built by aggregating the languages of each file in that repository. The top language in the graph determines the project's primary language. +``` +$ cat .gitattributes +project-docs/* linguist-documentation +docs/formatter.rb linguist-documentation=false +``` -The repository stats API, accessed through `#languages`, can be used on a directory: +### Using Emacs and Vim modelines -***API UPDATE*** +Alternatively, you can use Vim and Emacs style modelines to set the language for a single file. Modelines can be placed anywhere within a file and are respected when determining how to syntax-highlight a file on GitHub.com -Since [Version 3.0.0](https://github.com/github/linguist/releases/tag/v3.0.0) Linguist expects a git repository (in the form of a [Rugged::Repository](https://github.com/libgit2/rugged#repositories)) to be passed when initializing `Linguist::Repository`. +``` +Vim +vim: set filetype=prolog: +vim: set ft=cpp: +Emacs +-*- mode: php;-*- +``` + +## Usage + +Install the gem: + +``` +$ gem install github-linguist +``` + +Then use it in your application: ```ruby require 'rugged' @@ -51,146 +86,27 @@ project.language #=> "Ruby" project.languages #=> { "Ruby" => 119387 } ``` -These stats are also printed out by the `linguist` binary. You can use the +These stats are also printed out by the `linguist` executable. You can use the `--breakdown` flag, and the binary will also output the breakdown of files by language. You can try running `linguist` on the root directory in this repository itself: - $ bundle exec linguist --breakdown +``` +$ bundle exec linguist --breakdown - 100.00% Ruby +100.00% Ruby - Ruby: - Gemfile - Rakefile - bin/linguist - github-linguist.gemspec - lib/linguist.rb - lib/linguist/blob_helper.rb - lib/linguist/classifier.rb - lib/linguist/file_blob.rb - lib/linguist/generated.rb - lib/linguist/heuristics.rb - lib/linguist/language.rb - lib/linguist/lazy_blob.rb - lib/linguist/md5.rb - lib/linguist/repository.rb - lib/linguist/samples.rb - lib/linguist/tokenizer.rb - lib/linguist/version.rb - test/test_blob.rb - test/test_classifier.rb - test/test_heuristics.rb - test/test_language.rb - test/test_md5.rb - test/test_pedantic.rb - test/test_repository.rb - test/test_samples.rb - test/test_tokenizer.rb - -#### Ignore vendored files - -Checking other code into your git repo is a common practice. But this often inflates your project's language stats and may even cause your project to be labeled as another language. We are able to identify some of these files and directories and exclude them. - -```ruby -Linguist::FileBlob.new("vendor/plugins/foo.rb").vendored? # => true +Ruby: +Gemfile +Rakefile +bin/linguist +github-linguist.gemspec +lib/linguist.rb +… ``` -See [Linguist::BlobHelper#vendored?](https://github.com/github/linguist/blob/master/lib/linguist/blob_helper.rb) and [lib/linguist/vendor.yml](https://github.com/github/linguist/blob/master/lib/linguist/vendor.yml). +## Contributing -#### Generated file detection +Please check out our [contributing guidelines](CONTRIBUTING.md). -Not all plain text files are true source files. Generated files like minified js and compiled CoffeeScript can be detected and excluded from language stats. As an extra bonus, these files are suppressed in diffs. - -```ruby -Linguist::FileBlob.new("underscore.min.js").generated? # => true -``` - -See [Linguist::Generated#generated?](https://github.com/github/linguist/blob/master/lib/linguist/generated.rb). - -## Overrides - -Linguist supports custom overrides for language definitions and vendored paths. Add a `.gitattributes` file to your project using the keys `linguist-language` and `linguist-vendored` with the standard git-style path matchers for the files you want to override. - -Please note that the overrides currently only affect the language statistics for a repository and not the syntax-highlighting of files. - -``` -$ cat .gitattributes -*.rb linguist-language=Java - -$ linguist --breakdown -100.00% Java - -Java: -ruby_file.rb -``` - -By default, Linguist treats all of the paths defined in [lib/linguist/vendor.yml](https://github.com/github/linguist/blob/master/lib/linguist/vendor.yml) as vendored and therefore doesn't include them in the language statistics for a repository. Use the `linguist-vendored` attribute to vendor or un-vendor paths. - -``` -$ cat .gitattributes -special-vendored-path/* linguist-vendored -jquery.js linguist-vendored=false -``` - -## Installation - -Github.com is usually running the latest version of the `github-linguist` gem that is released on [RubyGems.org](http://rubygems.org/gems/github-linguist). - -But for development you are going to want to checkout out the source. To get it, clone the repo and run [Bundler](http://gembundler.com/) to install its dependencies. - - git clone https://github.com/github/linguist.git - cd linguist/ - bundle install - -To run the tests: - - bundle exec rake test - -### A note on language extensions - -Linguist has a number of methods available to it for identifying the language of a particular file. The initial lookup is based upon the extension of the file, possible file extensions are defined in an array called `extensions`. Take a look at this example for example for `Perl`: - -``` -Perl: - type: programming - ace_mode: perl - color: "#0298c3" - extensions: - - .pl - - .PL - - .perl - - .ph - - .plx - - .pm - - .pod - - .psgi - interpreters: - - perl -``` -Any of the extensions defined are valid but the first in this array should be the most popular. - -### Testing - -Sometimes getting the tests running can be too much work, especially if you don't have much Ruby experience. It's okay: be lazy and let our build bot [Travis](http://travis-ci.org/#!/github/linguist) run the tests for you. Just open a pull request and the bot will start cranking away. - -Here's our current build status, which is hopefully green: [![Build Status](https://secure.travis-ci.org/github/linguist.png?branch=master)](http://travis-ci.org/github/linguist) - -### Releasing - -If you are the current maintainer of this gem: - - 0. Create a branch for the release: `git checkout -b cut-release-vxx.xx.xx` - 0. Make sure your local dependencies are up to date: `bundle install` - 0. Ensure that samples are updated: `bundle exec rake samples` - 0. Ensure that tests are green: `bundle exec rake test` - 0. Bump gem version in `lib/linguist/version.rb`. For example, [like this](https://github.com/github/linguist/commit/8d2ea90a5ba3b2fe6e1508b7155aa4632eea2985). - 0. Make a PR to github/linguist. For example, [#1238](https://github.com/github/linguist/pull/1238). - 0. Build a local gem: `bundle exec rake build_gem` - 0. Testing: - 0. Bump the Gemfile and Gemfile.lock versions for an app which relies on this gem - 0. Install the new gem locally - 0. Test behavior locally, branch deploy, whatever needs to happen - 0. Merge github/linguist PR - 0. Tag and push: `git tag vx.xx.xx; git push --tags` - 0. Push to rubygems.org -- `gem push github-linguist-3.0.0.gem` +## diff --git a/Rakefile b/Rakefile index 470dcec9..b38486c0 100644 --- a/Rakefile +++ b/Rakefile @@ -3,13 +3,14 @@ require 'rake/clean' require 'rake/testtask' require 'yaml' require 'yajl' +require 'open-uri' task :default => :test Rake::TestTask.new -# Extend test task to check for samples -task :test => :check_samples +# Extend test task to check for samples and fetch latest Ace modes +task :test => [:check_samples, :fetch_ace_modes] desc "Check that we have samples.json generated" task :check_samples do @@ -18,6 +19,20 @@ task :check_samples do end end +desc "Fetch the latest Ace modes from its GitHub repository" +task :fetch_ace_modes do + ACE_FIXTURE_PATH = File.join('test', 'fixtures', 'ace_modes.json') + + File.delete(ACE_FIXTURE_PATH) if File.exist?(ACE_FIXTURE_PATH) + + begin + ace_github_modes = open("https://api.github.com/repos/ajaxorg/ace/contents/lib/ace/mode").read + File.write(ACE_FIXTURE_PATH, ace_github_modes) + rescue OpenURI::HTTPError, SocketError + # no internet? no problem. + end +end + task :samples do require 'linguist/samples' json = Yajl.dump(Linguist::Samples.data, :pretty => true) @@ -33,7 +48,7 @@ end task :build_grammars_gem do rm_rf "grammars" - sh "script/download-grammars" + sh "script/convert-grammars" sh "gem", "build", "github-linguist-grammars.gemspec" end diff --git a/github-linguist.gemspec b/github-linguist.gemspec index 578e823c..983db982 100644 --- a/github-linguist.gemspec +++ b/github-linguist.gemspec @@ -18,6 +18,7 @@ Gem::Specification.new do |s| s.add_dependency 'mime-types', '>= 1.19' s.add_dependency 'rugged', '~> 0.22.0b4' + s.add_development_dependency 'minitest', '>= 5.0' s.add_development_dependency 'mocha' s.add_development_dependency 'pry' s.add_development_dependency 'rake' diff --git a/grammars.yml b/grammars.yml index ce126d70..79248311 100644 --- a/grammars.yml +++ b/grammars.yml @@ -9,8 +9,6 @@ http://svn.textmate.org/trunk/Review/Bundles/Forth.tmbundle: - source.forth http://svn.textmate.org/trunk/Review/Bundles/Parrot.tmbundle: - source.parrot.pir -http://svn.textmate.org/trunk/Review/Bundles/Ruby%20Sass.tmbundle: -- source.sass http://svn.textmate.org/trunk/Review/Bundles/SecondLife%20LSL.tmbundle: - source.lsl http://svn.textmate.org/trunk/Review/Bundles/VHDL.tmbundle: @@ -20,393 +18,503 @@ http://svn.textmate.org/trunk/Review/Bundles/XQuery.tmbundle: https://bitbucket.org/Clams/sublimesystemverilog/get/default.tar.gz: - source.systemverilog - source.ucfconstraints -https://bitbucket.org/bitlang/sublime_cobol/raw/b0e9c44ac5f7a2fb553421aa986b35854cbfda4a/COBOL.tmLanguage: -- source.cobol https://fan.googlecode.com/hg-history/Build%201.0.55/adm/tools/textmate/Fan.tmbundle/Syntaxes/Fan.tmLanguage: - source.fan -https://github.com/AlanQuatermain/go-tmbundle: -- source.go -https://github.com/Anomareh/PHP-Twig.tmbundle: -- text.html.twig -https://github.com/Cirru/sublime-cirru/raw/master/Cirru.tmLanguage: -- source.cirru -https://github.com/Cykey/Sublime-Logos: -- source.logos -https://github.com/Drako/SublimeBrainfuck/raw/master/Brainfuck.tmLanguage: -- source.bf -https://github.com/JohnNilsson/awk-sublime/raw/master/AWK.tmLanguage: -- source.awk -https://github.com/JonBons/Sublime-SQF-Language: -- source.sqf -https://github.com/MarioRicalde/SCSS.tmbundle: -- source.scss -https://github.com/Oldes/Sublime-REBOL: -- source.rebol -https://github.com/PogiNate/Sublime-Inform: -- source.Inform7 -https://github.com/Red-Nova-Technologies/autoitv3-tmbundle: -- source.autoit.3 -https://github.com/SalGnt/Sublime-VimL: -- source.viml -https://github.com/Shammah/boo-sublime/raw/master/Boo.tmLanguage: -- source.boo -https://github.com/SublimeText/ColdFusion: +vendor/grammars/Agda.tmbundle: +- source.agda +vendor/grammars/Alloy.tmbundle: +- source.alloy +vendor/grammars/AutoHotkey/: +- source.ahk +vendor/grammars/CLIPS-sublime: +- source.clips +vendor/grammars/ColdFusion: - source.cfscript - source.cfscript.cfc - text.cfml.basic - text.html.cfm -https://github.com/SublimeText/NSIS: -- source.nsis -https://github.com/Varriount/NimLime: -- source.nimrod -- source.nimrod_filter -- source.nimrodcfg -https://github.com/angryant0007/VBDotNetSyntax: -- source.vbnet -https://github.com/aroben/ada.tmbundle/raw/c45eed4d5f98fe3bcbbffbb9e436601ab5bbde4b/Syntaxes/Ada.plist: -- source.ada -https://github.com/aroben/ruby.tmbundle@4636a3023153c3034eb6ffc613899ba9cf33b41f: -- source.ruby -- text.html.erb -https://github.com/asbjornenge/Docker.tmbundle: +vendor/grammars/Creole: +- text.html.creole +vendor/grammars/Docker.tmbundle: - source.dockerfile -https://github.com/atom/language-clojure: -- source.clojure -https://github.com/atom/language-coffee-script: -- source.coffee -- source.litcoffee -https://github.com/atom/language-csharp: -- source.cs -- source.csx -- source.nant-build -https://github.com/atom/language-javascript: -- source.js -- source.js.regexp -https://github.com/atom/language-python: -- source.python -- source.regexp.python -- text.python.traceback -https://github.com/atom/language-shellscript: -- source.shell -- text.shell-session -https://github.com/austinwagner/sublime-sourcepawn: -- source.sp -https://github.com/bfad/Sublime-Lasso: -- file.lasso -https://github.com/bholt/chapel-tmbundle: -- source.chapel -https://github.com/brandonwamboldt/sublime-nginx: -- source.nginx -https://github.com/bro/bro-sublime: -- source.bro -https://github.com/carsonoid/sublime_man_page_support/raw/master/man-groff.tmLanguage: -- text.groff -https://github.com/ccreutzig/sublime-MuPAD: -- source.mupad -https://github.com/cdwilson/nesC.tmbundle: -- source.nesc -https://github.com/christophevg/racket-tmbundle: +vendor/grammars/Elm.tmLanguage: +- source.elm +vendor/grammars/G-Code/: +- source.LS +- source.MCPOST +- source.MOD +- source.apt +- source.gcode +vendor/grammars/GDScript-sublime/: +- source.gdscript +vendor/grammars/Handlebars: +- text.html.handlebars +vendor/grammars/IDL-Syntax: +- source.webidl +vendor/grammars/InnoSetup/: +- source.inno +vendor/grammars/Isabelle.tmbundle: +- source.isabelle.root +- source.isabelle.theory +vendor/grammars/JSyntax/: +- source.j +vendor/grammars/Julia.tmbundle: +- source.julia +vendor/grammars/LiveScript.tmbundle: +- source.livescript +vendor/grammars/Modelica/: +- source.modelica +vendor/grammars/NSIS: +- source.nsis +vendor/grammars/NimLime: +- source.nim +- source.nim_filter +- source.nimcfg +vendor/grammars/PHP-Twig.tmbundle: +- text.html.twig +vendor/grammars/PogoScript.tmbundle/: +- source.pogoscript +vendor/grammars/RDoc.tmbundle: +- text.rdoc +vendor/grammars/Racket: - source.racket -https://github.com/clemos/haxe-sublime-bundle: +vendor/grammars/SCSS.tmbundle: +- source.scss +vendor/grammars/Scalate.tmbundle: +- source.scaml +- text.html.ssp +vendor/grammars/Slash.tmbundle: +- text.html.slash +vendor/grammars/Stata.tmbundle: +- source.mata +- source.stata +vendor/grammars/Sublime-Coq: +- source.coq +vendor/grammars/Sublime-HTTP: +- source.httpspec +vendor/grammars/Sublime-Inform: +- source.Inform7 +vendor/grammars/Sublime-Lasso: +- file.lasso +vendor/grammars/Sublime-Logos: +- source.logos +vendor/grammars/Sublime-Loom: +- source.loomscript +vendor/grammars/Sublime-Nit: +- source.nit +vendor/grammars/Sublime-QML: +- source.qml +vendor/grammars/Sublime-REBOL: +- source.rebol +vendor/grammars/Sublime-SQF-Language: +- source.sqf +vendor/grammars/Sublime-Text-2-OpenEdge-ABL: +- source.abl +vendor/grammars/Sublime-VimL: +- source.viml +vendor/grammars/SublimeBrainfuck: +- source.bf +vendor/grammars/SublimeClarion/: +- source.clarion +vendor/grammars/SublimePapyrus/: +- source.compiled-papyrus +- source.papyrus +- source.papyrus-assembly +vendor/grammars/SublimeXtend: +- source.xtend +vendor/grammars/TXL/: +- source.txl +vendor/grammars/Textmate-Gosu-Bundle: +- source.gosu.2 +vendor/grammars/VBDotNetSyntax: +- source.vbnet +vendor/grammars/Vala-TMBundle: +- source.vala +vendor/grammars/abap.tmbundle: +- source.abap +vendor/grammars/actionscript3-tmbundle: +- source.actionscript.3 +- text.html.asdoc +- text.xml.flex-config +vendor/grammars/ada.tmbundle: +- source.ada +vendor/grammars/ant.tmbundle: +- text.xml.ant +vendor/grammars/antlr.tmbundle: +- source.antlr +vendor/grammars/apache.tmbundle: +- source.apache-config +- source.apache-config.mod_perl +vendor/grammars/applescript.tmbundle: +- source.applescript +vendor/grammars/asp.tmbundle: +- source.asp +- text.html.asp +vendor/grammars/assembly.tmbundle: +- objdump.x86asm +- source.x86asm +vendor/grammars/atom-salt: +- source.python.salt +- source.yaml.salt +vendor/grammars/ats.sublime: +- source.ats +vendor/grammars/autoitv3-tmbundle: +- source.autoit.3 +vendor/grammars/awk-sublime: +- source.awk +vendor/grammars/bison.tmbundle: +- source.bison +vendor/grammars/boo-sublime: +- source.boo +vendor/grammars/bro-sublime: +- source.bro +vendor/grammars/c.tmbundle: +- source.c +- source.c++ +- source.c.platform +vendor/grammars/capnproto.tmbundle: +- source.capnp +vendor/grammars/carto-atom: +- source.css.mss +vendor/grammars/ceylon-sublimetext: +- module.ceylon +- source.ceylon +vendor/grammars/chapel-tmbundle: +- source.chapel +vendor/grammars/cmake.tmbundle: +- source.cache.cmake +- source.cmake +vendor/grammars/cool-tmbundle: +- source.cool +vendor/grammars/cpp-qt.tmbundle: +- source.c++.qt +- source.qmake +vendor/grammars/css.tmbundle: +- source.css +vendor/grammars/cucumber-tmbundle: +- source.ruby.rspec.cucumber.steps +- text.gherkin.feature +vendor/grammars/d.tmbundle: +- source.d +vendor/grammars/dart-sublime-bundle: +- source.dart +- source.pubspec +- text.dart-doccomments +vendor/grammars/desktop.tmbundle: +- source.desktop +vendor/grammars/diff.tmbundle: +- source.diff +vendor/grammars/dylan.tmbundle: +- source.dylan +- source.lid +- source.makegen +vendor/grammars/ebundles/Bundles/MSDOS batch file.tmbundle: +- source.dosbatch +vendor/grammars/ec.tmbundle/: +- source.c.ec +vendor/grammars/eiffel.tmbundle: +- source.eiffel +vendor/grammars/elixir-tmbundle: +- source.elixir +- text.elixir +- text.html.elixir +vendor/grammars/erlang.tmbundle: +- source.erlang +- text.html.erlang.yaws +vendor/grammars/factor: +- source.factor +- text.html.factor +vendor/grammars/fancy-tmbundle: +- source.fancy +vendor/grammars/fish-tmbundle: +- source.fish +vendor/grammars/fortran.tmbundle: +- source.fortran +- source.fortran.modern +vendor/grammars/fsharpbinding: +- source.fsharp +vendor/grammars/gap-tmbundle/: +- source.gap +vendor/grammars/gettext.tmbundle: +- source.po +vendor/grammars/gnuplot-tmbundle: +- source.gnuplot +vendor/grammars/go-tmbundle: +- source.go +vendor/grammars/grace-tmbundle/: +- source.grace +vendor/grammars/gradle.tmbundle: +- source.groovy.gradle +vendor/grammars/graphviz.tmbundle: +- source.dot +vendor/grammars/groovy.tmbundle: +- source.groovy +vendor/grammars/haskell.tmbundle: +- source.haskell +- text.tex.latex.haskell +vendor/grammars/haxe-sublime-bundle: - source.erazor - source.haxe.2 - source.hss.1 - source.hxml - source.nmml -https://github.com/cucumber/cucumber-tmbundle: -- source.ruby.rspec.cucumber.steps -- text.gherkin.feature -https://github.com/daaain/Handlebars/raw/master/Handlebars.tmLanguage: -- text.html.handlebars -https://github.com/davidpeckham/powershell.tmbundle: -- source.powershell -https://github.com/davidrios/jade-tmbundle: -- source.jade -- source.pyjade -https://github.com/elixir-lang/elixir-tmbundle: -- source.elixir -- text.elixir -- text.html.elixir -https://github.com/ericzou/ebundles/raw/master/Bundles/MSDOS%20batch%20file.tmbundle/Syntaxes/MSDOS%20batch%20file.tmLanguage: -- source.dosbatch -https://github.com/euler0/sublime-glsl/raw/master/GLSL.tmLanguage: -- source.glsl -https://github.com/fancy-lang/fancy-tmbundle: -- source.fancy -https://github.com/fushnisoft/SublimeClarion: -- source.clarion -https://github.com/fsharp/fsharpbinding: -- source.fsharp -https://github.com/gingerbeardman/monkey.tmbundle: -- source.monkey -https://github.com/guillermooo/dart-sublime-bundle/raw/master/Dart.tmLanguage: -- source.dart -https://github.com/harrism/sublimetext-cuda-cpp/raw/master/cuda-c%2B%2B.tmLanguage: -- source.cuda-c++ -https://github.com/hww3/pike-textmate: -- source.pike -https://github.com/jeancharles-roger/ceylon-sublimetext/raw/master/Ceylon.tmLanguage: -- source.ceylon -https://github.com/jfairbank/Sublime-Text-2-OpenEdge-ABL: -- source.abl -https://github.com/jhasse/sublime-rust: -- source.rust -https://github.com/johanasplund/sublime-befunge/raw/master/Befunge-93.tmLanguage: -- source.befunge -https://github.com/joshaven/RDoc.tmbundle: -- text.rdoc -https://github.com/jpcamara/Textmate-Gosu-Bundle/raw/master/Gosu.tmbundle/Syntaxes/Gosu.tmLanguage: -- source.gosu.2 -https://github.com/kswedberg/jquery-tmbundle: -- source.js.jquery -https://github.com/laughedelic/sublime-idris/raw/master/Idris.tmLanguage: -- source.idris -https://github.com/lavrton/sublime-better-typescript: -- source.ts -https://github.com/leafo/moonscript-tmbundle: -- source.moonscript -https://github.com/lunixbochs/x86-assembly-textmate-bundle: -- source.asm.x86 -https://github.com/macekond/Alloy.tmbundle: -- source.alloy -https://github.com/mads379/opa.tmbundle: -- source.opa -https://github.com/mads379/scala.tmbundle: -- source.sbt -- source.scala -https://github.com/marconi/mako-tmbundle: -- text.html.mako -https://github.com/mattfoster/gnuplot-tmbundle: -- source.gnuplot -https://github.com/mgalloy/idl.tmbundle: +vendor/grammars/html.tmbundle: +- text.html.basic +vendor/grammars/idl.tmbundle: - source.idl - source.idl-dlm - text.idl-idldoc -https://github.com/michaeledgar/protobuf-tmbundle: -- source.protobuf -https://github.com/mkolosick/Sublime-Coq/raw/master/Coq.tmLanguage: -- source.coq -https://github.com/mokus0/Agda.tmbundle: -- source.agda -https://github.com/nanoant/Julia.tmbundle: -- source.julia -https://github.com/nanoant/assembly.tmbundle/raw/master/Syntaxes/objdump%20C%2B%2B.tmLanguage: -- objdump.x86asm -https://github.com/nilium/ooc.tmbundle: -- source.ooc -https://github.com/paulmillr/LiveScript.tmbundle: -- source.livescript -https://github.com/pferruggiaro/sublime-tea: -- source.tea -https://github.com/puppet-textmate-bundle/puppet-textmate-bundle: -- source.puppet -https://github.com/pvl/abap.tmbundle: -- source.abap -https://github.com/scalate/Scalate.tmbundle: -- source.scaml -- text.html.ssp -https://github.com/shadanan/mathematica-tmbundle: -- source.mathematica -https://github.com/shellderp/sublime-robot-plugin: -- text.robot -https://github.com/simongregory/actionscript3-tmbundle: -- source.actionscript.3 -- text.html.asdoc -- text.xml.flex-config -https://github.com/skozlovf/Sublime-QML: -- source.qml -https://github.com/slash-lang/Slash.tmbundle: -- text.html.slash -https://github.com/slavapestov/factor/raw/master/misc/Factor.tmbundle/Syntaxes/Factor.tmLanguage: -- source.factor -https://github.com/slim-template/ruby-slim.tmbundle: -- text.slim -https://github.com/staltz/SublimeXtend: -- source.xtend -https://github.com/statatmbundle/Stata.tmbundle: -- source.mata -- source.stata -https://github.com/technosophos/Vala-TMBundle: -- source.vala -https://github.com/textmate/ant.tmbundle: -- text.xml.ant -https://github.com/textmate/antlr.tmbundle: -- source.antlr -https://github.com/textmate/apache.tmbundle: -- source.apache-config -- source.apache-config.mod_perl -https://github.com/textmate/applescript.tmbundle: -- source.applescript -https://github.com/textmate/asp.tmbundle: -- source.asp -- text.html.asp -https://github.com/textmate/bison.tmbundle: -- source.bison -https://github.com/textmate/c.tmbundle: -- source.c -- source.c++ -- source.c.platform -https://github.com/textmate/capnproto.tmbundle: -- source.capnp -https://github.com/textmate/cmake.tmbundle: -- source.cache.cmake -- source.cmake -https://github.com/textmate/cpp-qt.tmbundle: -- source.c++.qt -- source.qmake -https://github.com/textmate/css.tmbundle: -- source.css -https://github.com/textmate/d.tmbundle: -- source.d -https://github.com/textmate/diff.tmbundle: -- source.diff -https://github.com/textmate/dylan.tmbundle: -- source.dylan -- source.lid -- source.makegen -https://github.com/textmate/eiffel.tmbundle: -- source.eiffel -https://github.com/textmate/erlang.tmbundle: -- source.erlang -- text.html.erlang.yaws -https://github.com/textmate/fortran.tmbundle: -- source.fortran -- source.fortran.modern -https://github.com/textmate/gettext.tmbundle: -- source.po -https://github.com/textmate/graphviz.tmbundle: -- source.dot -https://github.com/textmate/groovy.tmbundle: -- source.groovy -https://github.com/textmate/haskell.tmbundle: -- source.haskell -- text.tex.latex.haskell -https://github.com/textmate/html.tmbundle: -- text.html.basic -https://github.com/textmate/ini.tmbundle: +vendor/grammars/ini.tmbundle: - source.ini -https://github.com/textmate/io.tmbundle: +vendor/grammars/io.tmbundle: - source.io -https://github.com/textmate/java.tmbundle: +vendor/grammars/ioke-outdated: +- source.ioke +vendor/grammars/jade-tmbundle: +- source.jade +- source.pyjade +vendor/grammars/jasmin-sublime: +- source.jasmin +vendor/grammars/java.tmbundle: - source.java - source.java-properties - text.html.jsp - text.junit-test-report -https://github.com/textmate/javadoc.tmbundle: +vendor/grammars/javadoc.tmbundle: - text.html.javadoc -https://github.com/textmate/javascript-objective-j.tmbundle: +vendor/grammars/javascript-objective-j.tmbundle: - source.js.objj -https://github.com/textmate/json.tmbundle: +vendor/grammars/jquery-tmbundle: +- source.js.jquery +vendor/grammars/json.tmbundle: - source.json -https://github.com/textmate/latex.tmbundle: +vendor/grammars/kotlin-sublime-package: +- source.Kotlin +vendor/grammars/language-clojure: +- source.clojure +vendor/grammars/language-coffee-script: +- source.coffee +- source.litcoffee +vendor/grammars/language-csharp: +- source.cs +- source.csx +- source.nant-build +vendor/grammars/language-gfm: +- source.gfm +vendor/grammars/language-hy: +- source.hy +vendor/grammars/language-javascript: +- source.js +- source.js.regexp +vendor/grammars/language-python: +- source.python +- source.regexp.python +- text.python.console +- text.python.traceback +vendor/grammars/language-shellscript: +- source.shell +- text.shell-session +vendor/grammars/language-yaml: +- source.yaml +vendor/grammars/latex.tmbundle: - text.bibtex - text.log.latex - text.tex - text.tex.latex - text.tex.latex.beamer - text.tex.latex.memoir -https://github.com/textmate/less.tmbundle: +vendor/grammars/less.tmbundle: - source.css.less -https://github.com/textmate/lilypond.tmbundle: +vendor/grammars/lilypond.tmbundle: - source.lilypond -https://github.com/textmate/lisp.tmbundle: +vendor/grammars/liquid.tmbundle: +- text.html.liquid +vendor/grammars/lisp.tmbundle: - source.lisp -https://github.com/textmate/logtalk.tmbundle: +vendor/grammars/llvm.tmbundle: +- source.llvm +vendor/grammars/logtalk.tmbundle: - source.logtalk -https://github.com/textmate/lua.tmbundle: +vendor/grammars/lua.tmbundle: - source.lua -https://github.com/textmate/make.tmbundle: +vendor/grammars/make.tmbundle: - source.makefile -https://github.com/textmate/markdown.tmbundle: -- text.html.markdown -https://github.com/textmate/matlab.tmbundle: +vendor/grammars/mako-tmbundle: +- text.html.mako +vendor/grammars/mathematica-tmbundle: +- source.mathematica +vendor/grammars/matlab.tmbundle: - source.matlab - source.octave -https://github.com/textmate/maven.tmbundle: +vendor/grammars/maven.tmbundle: - text.xml.pom -https://github.com/textmate/nemerle.tmbundle: +vendor/grammars/mediawiki.tmbundle/: +- text.html.mediawiki +vendor/grammars/mercury-tmlanguage: +- source.mercury +vendor/grammars/monkey.tmbundle: +- source.monkey +vendor/grammars/moonscript-tmbundle: +- source.moonscript +vendor/grammars/nemerle.tmbundle: - source.nemerle -https://github.com/textmate/ninja.tmbundle: +vendor/grammars/nesC.tmbundle: +- source.nesc +vendor/grammars/ninja.tmbundle: - source.ninja -https://github.com/textmate/objective-c.tmbundle: +vendor/grammars/objective-c.tmbundle: - source.objc - source.objc++ - source.objc.platform - source.strings -https://github.com/textmate/ocaml.tmbundle: +vendor/grammars/ocaml.tmbundle: - source.camlp4.ocaml - source.ocaml - source.ocamllex - source.ocamlyacc -https://github.com/textmate/pascal.tmbundle: +vendor/grammars/ooc.tmbundle: +- source.ooc +vendor/grammars/opa.tmbundle: +- source.opa +vendor/grammars/oz-tmbundle/Syntaxes/Oz.tmLanguage: +- source.oz +vendor/grammars/pascal.tmbundle: - source.pascal -https://github.com/textmate/perl.tmbundle: +vendor/grammars/perl.tmbundle: - source.perl -https://github.com/textmate/php-smarty.tmbundle: +vendor/grammars/php-smarty.tmbundle: - source.smarty -https://github.com/textmate/php.tmbundle: +vendor/grammars/php.tmbundle: - text.html.php -https://github.com/textmate/postscript.tmbundle: +vendor/grammars/pike-textmate: +- source.pike +vendor/grammars/postscript.tmbundle: - source.postscript -https://github.com/textmate/processing.tmbundle: +vendor/grammars/powershell: +- source.powershell +vendor/grammars/processing.tmbundle: - source.processing -https://github.com/textmate/prolog.tmbundle: +vendor/grammars/prolog.tmbundle: - source.prolog -https://github.com/textmate/python-django.tmbundle: +vendor/grammars/protobuf-tmbundle: +- source.protobuf +vendor/grammars/puppet-textmate-bundle: +- source.puppet +vendor/grammars/python-django.tmbundle: - source.python.django - text.html.django -https://github.com/textmate/r.tmbundle: +vendor/grammars/r.tmbundle: - source.r - text.tex.latex.rd -https://github.com/textmate/restructuredtext.tmbundle: +vendor/grammars/restructuredtext.tmbundle: - text.restructuredtext -https://github.com/textmate/ruby-haml.tmbundle: +vendor/grammars/ruby-haml.tmbundle: - text.haml -https://github.com/textmate/ruby-on-rails-tmbundle: +vendor/grammars/ruby-on-rails-tmbundle: - source.js.erb.rails - source.ruby.rails - source.ruby.rails.rjs - source.sql.ruby - text.html.erb.rails -https://github.com/textmate/scheme.tmbundle: +vendor/grammars/ruby-slim.tmbundle: +- text.slim +vendor/grammars/ruby.tmbundle: +- source.ruby +- text.html.erb +vendor/grammars/sas.tmbundle: +- source.SASLog +- source.sas +vendor/grammars/sass-textmate-bundle: +- source.sass +vendor/grammars/scala.tmbundle: +- source.sbt +- source.scala +vendor/grammars/scheme.tmbundle: - source.scheme -https://github.com/textmate/scilab.tmbundle: +vendor/grammars/scilab.tmbundle: - source.scilab -https://github.com/textmate/sql.tmbundle: +vendor/grammars/smalltalk-tmbundle: +- source.smalltalk +vendor/grammars/sql.tmbundle: - source.sql -https://github.com/textmate/standard-ml.tmbundle: +vendor/grammars/standard-ml.tmbundle: - source.cm - source.ml -https://github.com/textmate/swift.tmbundle: +vendor/grammars/sublime-MuPAD: +- source.mupad +vendor/grammars/sublime-apl/: +- source.apl +vendor/grammars/sublime-befunge: +- source.befunge +vendor/grammars/sublime-better-typescript: +- source.ts +vendor/grammars/sublime-bsv: +- source.bsv +vendor/grammars/sublime-cirru: +- source.cirru +vendor/grammars/sublime-glsl: +- source.essl +- source.glsl +vendor/grammars/sublime-golo/: +- source.golo +vendor/grammars/sublime-idris: +- source.idris +vendor/grammars/sublime-mask: +- source.mask +vendor/grammars/sublime-nginx: +- source.nginx +vendor/grammars/sublime-nix: +- source.nix +vendor/grammars/sublime-opal/: +- source.opal +- source.opalsysdefs +vendor/grammars/sublime-robot-plugin: +- text.robot +vendor/grammars/sublime-rust: +- source.rust +vendor/grammars/sublime-sourcepawn: +- source.sp +vendor/grammars/sublime-spintools/: +- source.regexp.spin +- source.spin +vendor/grammars/sublime-tea: +- source.tea +vendor/grammars/sublime-text-ox/: +- source.ox +vendor/grammars/sublime_cobol: +- source.acucobol +- source.cobol +- source.opencobol +vendor/grammars/sublime_man_page_support: +- source.man +- text.groff +vendor/grammars/sublimetext-cuda-cpp: +- source.cuda-c++ +vendor/grammars/swift.tmbundle: - source.swift -https://github.com/textmate/tcl.tmbundle: +vendor/grammars/tcl.tmbundle: - source.tcl - text.html.tcl -https://github.com/textmate/text.tmbundle: +vendor/grammars/text.tmbundle: - text.plain -https://github.com/textmate/textile.tmbundle: +vendor/grammars/textile.tmbundle: - text.html.textile -https://github.com/textmate/textmate.tmbundle: +vendor/grammars/textmate.tmbundle: - source.regexp.oniguruma - source.tm-properties -https://github.com/textmate/thrift.tmbundle: +vendor/grammars/thrift.tmbundle: - source.thrift -https://github.com/textmate/toml.tmbundle: +vendor/grammars/toml.tmbundle: - source.toml -https://github.com/textmate/verilog.tmbundle: +vendor/grammars/turtle.tmbundle: +- source.sparql +- source.turtle +vendor/grammars/verilog.tmbundle: - source.verilog -https://github.com/textmate/xml.tmbundle: +vendor/grammars/x86-assembly-textmate-bundle: +- source.asm.x86 +vendor/grammars/xml.tmbundle: - text.xml - text.xml.xsl -https://github.com/textmate/yaml.tmbundle: -- source.yaml -https://github.com/tomas-stefano/smalltalk-tmbundle: -- source.smalltalk -https://github.com/vic/ioke-outdated/raw/master/share/TextMate/Ioke.tmbundle/Syntaxes/Ioke.tmLanguage: -- source.ioke -https://github.com/vkostyukov/kotlin-sublime-package: -- source.Kotlin -https://github.com/vmg/zephir-sublime: +vendor/grammars/zephir-sublime: - source.php.zephir -https://github.com/whitequark/llvm.tmbundle: -- source.llvm diff --git a/lib/linguist.rb b/lib/linguist.rb index 3714b5a0..ff9fc3a2 100644 --- a/lib/linguist.rb +++ b/lib/linguist.rb @@ -4,4 +4,5 @@ require 'linguist/heuristics' require 'linguist/language' require 'linguist/repository' require 'linguist/samples' +require 'linguist/shebang' require 'linguist/version' diff --git a/lib/linguist/blob_helper.rb b/lib/linguist/blob_helper.rb index c368b4d0..56c15f02 100644 --- a/lib/linguist/blob_helper.rb +++ b/lib/linguist/blob_helper.rb @@ -236,6 +236,21 @@ module Linguist name =~ VendoredRegexp ? true : false end + documentation_paths = YAML.load_file(File.expand_path("../documentation.yml", __FILE__)) + DocumentationRegexp = Regexp.new(documentation_paths.join('|')) + + # Public: Is the blob in a documentation directory? + # + # Documentation files are ignored by language statistics. + # + # See "documentation.yml" for a list of documentation conventions that match + # this pattern. + # + # Return true or false + def documentation? + name =~ DocumentationRegexp ? true : false + end + # Public: Get each line of data # # Requires Blob#data @@ -317,5 +332,15 @@ module Linguist def tm_scope language && language.tm_scope end + + DETECTABLE_TYPES = [:programming, :markup].freeze + + # Internal: Should this blob be included in repository language statistics? + def include_in_language_stats? + !vendored? && + !documentation? && + !generated? && + language && DETECTABLE_TYPES.include?(language.type) + end end end diff --git a/lib/linguist/classifier.rb b/lib/linguist/classifier.rb index 5370bdd8..89a0df2f 100644 --- a/lib/linguist/classifier.rb +++ b/lib/linguist/classifier.rb @@ -3,6 +3,25 @@ require 'linguist/tokenizer' module Linguist # Language bayesian classifier. class Classifier + # Public: Use the classifier to detect language of the blob. + # + # blob - An object that quacks like a blob. + # possible_languages - Array of Language objects + # + # Examples + # + # Classifier.call(FileBlob.new("path/to/file"), [ + # Language["Ruby"], Language["Python"] + # ]) + # + # Returns an Array of Language objects, most probable first. + def self.call(blob, possible_languages) + language_names = possible_languages.map(&:name) + classify(Samples.cache, blob.data, language_names).map do |name, _| + Language[name] # Return the actual Language objects + end + end + # Public: Train classifier that data is a certain language. # # db - Hash classifier database object diff --git a/lib/linguist/documentation.yml b/lib/linguist/documentation.yml new file mode 100644 index 00000000..b884cd35 --- /dev/null +++ b/lib/linguist/documentation.yml @@ -0,0 +1,19 @@ +# Documentation files and directories are excluded from language +# statistics. +# +# Lines in this file are Regexps that are matched against the file +# pathname. +# +# Please add additional test coverage to +# `test/test_blob.rb#test_documentation` if you make any changes. + +## Documentation Conventions ## + +- ^docs?/ +- ^Documentation/ + +- (^|/)CONTRIBUTING(\.|$) +- (^|/)COPYING(\.|$) +- (^|/)INSTALL(\.|$) +- (^|/)LICEN[CS]E(\.|$) +- (^|/)README(\.|$) diff --git a/lib/linguist/generated.rb b/lib/linguist/generated.rb index 291fa8bd..50dbc58d 100644 --- a/lib/linguist/generated.rb +++ b/lib/linguist/generated.rb @@ -51,20 +51,20 @@ module Linguist # # Return true or false def generated? - minified_files? || - compiled_coffeescript? || xcode_file? || - generated_parser? || - generated_net_docfile? || generated_net_designer_file? || - generated_postscript? || - generated_protocol_buffer? || - generated_jni_header? || composer_lock? || node_modules? || godeps? || - vcr_cassette? || - generated_by_zephir? + generated_by_zephir? || + minified_files? || + compiled_coffeescript? || + generated_parser? || + generated_net_docfile? || + generated_postscript? || + generated_protocol_buffer? || + generated_jni_header? || + vcr_cassette? end # Internal: Is the blob an Xcode file? diff --git a/lib/linguist/heuristics.rb b/lib/linguist/heuristics.rb index 13f0173f..b82a5de4 100644 --- a/lib/linguist/heuristics.rb +++ b/lib/linguist/heuristics.rb @@ -1,158 +1,233 @@ module Linguist # A collection of simple heuristics that can be used to better analyze languages. class Heuristics - ACTIVE = true - - # Public: Given an array of String language names, - # apply heuristics against the given data and return an array - # of matching languages, or nil. + # Public: Use heuristics to detect language of the blob. # - # data - Array of tokens or String data to analyze. - # languages - Array of language name Strings to restrict to. + # blob - An object that quacks like a blob. + # possible_languages - Array of Language objects # - # Returns an array of Languages or [] - def self.find_by_heuristics(data, languages) - if active? - result = [] + # Examples + # + # Heuristics.call(FileBlob.new("path/to/file"), [ + # Language["Ruby"], Language["Python"] + # ]) + # + # Returns an Array of languages, or empty if none matched or were inconclusive. + def self.call(blob, languages) + data = blob.data - if languages.all? { |l| ["Perl", "Prolog"].include?(l) } - result = disambiguate_pl(data) - end - if languages.all? { |l| ["ECL", "Prolog"].include?(l) } - result = disambiguate_ecl(data) - end - if languages.all? { |l| ["IDL", "Prolog"].include?(l) } - result = disambiguate_pro(data) - end - if languages.all? { |l| ["Common Lisp", "OpenCL"].include?(l) } - result = disambiguate_cl(data) - end - if languages.all? { |l| ["Hack", "PHP"].include?(l) } - result = disambiguate_hack(data) - end - if languages.all? { |l| ["Scala", "SuperCollider"].include?(l) } - result = disambiguate_sc(data) - end - if languages.all? { |l| ["AsciiDoc", "AGS Script"].include?(l) } - result = disambiguate_asc(data) - end - if languages.all? { |l| ["FORTRAN", "Forth"].include?(l) } - result = disambiguate_f(data) - end - return result + @heuristics.each do |heuristic| + return Array(heuristic.call(data)) if heuristic.matches?(languages) + end + + [] # No heuristics matched + end + + # Internal: Define a new heuristic. + # + # languages - String names of languages to disambiguate. + # heuristic - Block which takes data as an argument and returns a Language or nil. + # + # Examples + # + # disambiguate "Perl", "Prolog" do |data| + # if data.include?("use strict") + # Language["Perl"] + # elsif data.include?(":-") + # Language["Prolog"] + # end + # end + # + def self.disambiguate(*languages, &heuristic) + @heuristics << new(languages, &heuristic) + end + + # Internal: Array of defined heuristics + @heuristics = [] + + # Internal + def initialize(languages, &heuristic) + @languages = languages + @heuristic = heuristic + end + + # Internal: Check if this heuristic matches the candidate languages. + def matches?(candidates) + candidates.any? && candidates.all? { |l| @languages.include?(l.name) } + end + + # Internal: Perform the heuristic + def call(data) + @heuristic.call(data) + end + + # Common heuristics + ObjectiveCRegex = /^[ \t]*@(interface|class|protocol|property|end|synchronised|selector|implementation)\b/ + + disambiguate "BitBake", "BlitzBasic" do |data| + if /^\s*; /.match(data) || data.include?("End Function") + Language["BlitzBasic"] + elsif /^\s*(# |include|require)\b/.match(data) + Language["BitBake"] end end - # .h extensions are ambiguous between C, C++, and Objective-C. - # We want to shortcut look for Objective-C _and_ now C++ too! - # - # Returns an array of Languages or [] - def self.disambiguate_c(data) - matches = [] - if data.include?("@interface") - matches << Language["Objective-C"] - elsif data.include?("#include ") - matches << Language["C++"] + disambiguate "C#", "Smalltalk" do |data| + if /![\w\s]+methodsFor: /.match(data) + Language["Smalltalk"] + elsif /^\s*namespace\s*[\w\.]+\s*{/.match(data) || /^\s*\/\//.match(data) + Language["C#"] end - matches end - def self.disambiguate_pl(data) - matches = [] - if data.include?("use strict") - matches << Language["Perl"] + disambiguate "Objective-C", "C++", "C" do |data| + if ObjectiveCRegex.match(data) + Language["Objective-C"] + elsif (/^\s*#\s*include <(cstdint|string|vector|map|list|array|bitset|queue|stack|forward_list|unordered_map|unordered_set|(i|o|io)stream)>/.match(data) || + /^\s*template\s*")) - matches << Language["XML"] + disambiguate "GAP", "Scilab" do |data| + if (data.include?("gap> ")) + Language["GAP"] + # Heads up - we don't usually write heuristics like this (with no regex match) else - matches << Language["TypeScript"] + Language["Scilab"] end - matches end - def self.disambiguate_cl(data) - matches = [] + disambiguate "Common Lisp", "OpenCL", "Cool" do |data| if data.include?("(defun ") - matches << Language["Common Lisp"] + Language["Common Lisp"] + elsif /^class/x.match(data) + Language["Cool"] elsif /\/\* |\/\/ |^\}/.match(data) - matches << Language["OpenCL"] + Language["OpenCL"] end - matches end - def self.disambiguate_r(data) - matches = [] - matches << Language["Rebol"] if /\bRebol\b/i.match(data) - matches << Language["R"] if data.include?("<-") - matches - end - - def self.disambiguate_hack(data) - matches = [] + disambiguate "Hack", "PHP" do |data| if data.include?(" 0 - data = blob.data - - # Check if there's a shebang line and use that as authoritative - if (result = find_by_shebang(data)) && !result.empty? - return result.first - - # More than one language with that extension. We need to make a choice. - elsif possible_languages.length > 1 - - # First try heuristics - - possible_language_names = possible_languages.map(&:name) - heuristic_languages = Heuristics.find_by_heuristics(data, possible_language_names) - - # If there are multiple possible languages returned from heuristics - # then reduce language candidates for Bayesian classifier here. - if heuristic_languages.size > 1 - possible_language_names = heuristic_languages.map(&:name) - end - - if heuristic_languages.size == 1 - return heuristic_languages.first - # Lastly, fall back to the probabilistic classifier. - elsif classified = Classifier.classify(Samples.cache, data, possible_language_names).first - # Return the actual Language object based of the string language name (i.e., first element of `#classify`) - return Language[classified[0]] - end + # Call each strategy until one candidate is returned. + STRATEGIES.reduce([]) do |languages, strategy| + candidates = strategy.call(blob, languages) + if candidates.size == 1 + return candidates.first + elsif candidates.size > 1 + # More than one candidate was found, pass them to the next strategy. + candidates + else + # No candiates were found, pass on languages from the previous strategy. + languages end - end + end.first end # Public: Get all Languages @@ -185,7 +150,7 @@ module Linguist # Language.find_by_alias('cpp') # # => # # - # Returns the Lexer or nil if none was found. + # Returns the Language or nil if none was found. def self.find_by_alias(name) name && @alias_index[name.downcase] end @@ -229,21 +194,27 @@ module Linguist @extension_index[extname] end - # Public: Look up Languages by shebang line. + # DEPRECATED + def self.find_by_shebang(data) + @interpreter_index[Shebang.interpreter(data)] + end + + # Public: Look up Languages by interpreter. # - # data - Array of tokens or String data to analyze. + # interpreter - String of interpreter name # # Examples # - # Language.find_by_shebang("#!/bin/bash\ndate;") + # Language.find_by_interpreter("bash") # # => [#] # # Returns the matching Language - def self.find_by_shebang(data) - @interpreter_index[Linguist.interpreter_from_shebang(data)] + def self.find_by_interpreter(interpreter) + @interpreter_index[interpreter] end - # Public: Look up Language by its name or lexer. + + # Public: Look up Language by its name. # # name - The String name of the Language # @@ -267,7 +238,7 @@ module Linguist # # This list is configured in "popular.yml". # - # Returns an Array of Lexers. + # Returns an Array of Languages. def self.popular @popular ||= all.select(&:popular?).sort_by { |lang| lang.name.downcase } end @@ -279,7 +250,7 @@ module Linguist # # This list is created from all the languages not listed in "popular.yml". # - # Returns an Array of Lexers. + # Returns an Array of Languages. def self.unpopular @unpopular ||= all.select(&:unpopular?).sort_by { |lang| lang.name.downcase } end @@ -293,8 +264,12 @@ module Linguist # Public: A List of languages compatible with Ace. # + # TODO: Remove this method in a 5.x release. Every language now needs an ace_mode + # key, so this function isn't doing anything unique anymore. + # # Returns an Array of Languages. def self.ace_modes + warn "This method will be deprecated in a future 5.x release. Every language now has an `ace_mode` set." @ace_modes ||= all.select(&:ace_mode).sort_by { |lang| lang.name.downcase } end @@ -395,11 +370,6 @@ module Linguist # Returns the name String attr_reader :search_term - # Public: Get Lexer - # - # Returns the Lexer - attr_reader :lexer - # Public: Get the name of a TextMate-compatible scope # # Returns the scope @@ -515,16 +485,6 @@ module Linguist @searchable end - # Public: Highlight syntax of text - # - # text - String of code to be highlighted - # options - A Hash of options (defaults to {}) - # - # Returns html String - def colorize(text, options = {}) - lexer.highlight(text, options) - end - # Public: Return name as String representation def to_s name @@ -568,7 +528,7 @@ module Linguist if extnames = extensions[name] extnames.each do |extname| - if !options['extensions'].include?(extname) + if !options['extensions'].index { |x| x.end_with? extname } warn "#{name} has a sample with extension (#{extname}) that isn't explicitly defined in languages.yml" unless extname == '.script!' options['extensions'] << extname end @@ -600,7 +560,6 @@ module Linguist :color => options['color'], :type => options['type'], :aliases => options['aliases'], - :lexer => options['lexer'], :tm_scope => options['tm_scope'], :ace_mode => options['ace_mode'], :wrap => options['wrap'], diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index 050e7dcf..4673d3e2 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -3,7 +3,9 @@ # type - Either data, programming, markup, prose, or nil # aliases - An Array of additional aliases (implicitly # includes name.downcase) -# ace_mode - A String name of Ace Mode (if available) +# ace_mode - A String name of the Ace Mode used for highlighting whenever +# a file is edited. This must match one of the filenames in http://git.io/3XO_Cg. +# Use "text" if a mode does not exist. # wrap - Boolean wrap to enable line wrapping (default: false) # extensions - An Array of associated extensions (the first one is # considered the primary extension) @@ -26,6 +28,7 @@ ABAP: type: programming extensions: - .abap + ace_mode: abap AGS Script: type: programming @@ -36,12 +39,14 @@ AGS Script: - .asc - .ash tm_scope: source.c++ + ace_mode: c_cpp ANTLR: type: programming color: "#9DC3FF" extensions: - .g4 + ace_mode: text APL: type: programming @@ -49,12 +54,14 @@ APL: extensions: - .apl - .dyalog - tm_scope: none + tm_scope: source.apl + ace_mode: text ASP: type: programming color: "#6a40fd" search_term: aspx-vb + tm_scope: text.html.asp aliases: - aspx - aspx-vb @@ -66,6 +73,7 @@ ASP: - .asmx - .aspx - .axd + ace_mode: text ATS: type: programming @@ -74,10 +82,10 @@ ATS: - ats2 extensions: - .dats - - .atxt - .hats - .sats - tm_scope: source.ocaml + tm_scope: source.ats + ace_mode: ocaml ActionScript: type: programming @@ -90,6 +98,7 @@ ActionScript: - as3 extensions: - .as + ace_mode: actionscript Ada: type: programming @@ -100,18 +109,21 @@ Ada: - .ads aliases: - ada95ada2005 + ace_mode: ada Agda: type: programming color: "#467C91" extensions: - .agda + ace_mode: text Alloy: type: programming # 'modeling' would be more appropiate color: "#cc5c24" extensions: - .als + ace_mode: text Ant Build System: type: data @@ -119,6 +131,7 @@ Ant Build System: filenames: - ant.xml - build.xml + ace_mode: xml ApacheConf: type: markup @@ -129,12 +142,14 @@ ApacheConf: - .apacheconf - .conf tm_scope: source.apache-config + ace_mode: apache_conf Apex: type: programming extensions: - .cls tm_scope: source.java + ace_mode: java AppleScript: type: programming @@ -145,6 +160,7 @@ AppleScript: - .scpt interpreters: - osascript + ace_mode: applescript Arc: type: programming @@ -152,6 +168,7 @@ Arc: extensions: - .arc tm_scope: none + ace_mode: text Arduino: type: programming @@ -159,6 +176,7 @@ Arduino: extensions: - .ino tm_scope: source.c++ + ace_mode: c_cpp AsciiDoc: type: prose @@ -176,6 +194,7 @@ AspectJ: extensions: - .aj tm_scope: none + ace_mode: text Assembly: type: programming @@ -187,13 +206,16 @@ Assembly: - .asm - .ASM - .a51 + - .nasm tm_scope: source.asm.x86 + ace_mode: assembly_x86 Augeas: type: programming extensions: - .aug tm_scope: none + ace_mode: text AutoHotkey: type: programming @@ -203,7 +225,8 @@ AutoHotkey: extensions: - .ahk - .ahkl - tm_scope: none + tm_scope: source.ahk + ace_mode: autohotkey AutoIt: type: programming @@ -215,6 +238,7 @@ AutoIt: extensions: - .au3 tm_scope: source.autoit.3 + ace_mode: autohotkey Awk: type: programming @@ -229,6 +253,7 @@ Awk: - gawk - mawk - nawk + ace_mode: text Batchfile: type: programming @@ -243,16 +268,26 @@ Batchfile: - .bat - .cmd tm_scope: source.dosbatch + ace_mode: batchfile Befunge: extensions: - .befunge + ace_mode: text Bison: type: programming tm_scope: source.bison extensions: - .y + ace_mode: text + +BitBake: + type: programming + tm_scope: none + extensions: + - .bb + ace_mode: text BlitzBasic: type: programming @@ -265,6 +300,7 @@ BlitzBasic: - .bb - .decls tm_scope: source.blitzmax + ace_mode: text BlitzMax: type: programming @@ -273,45 +309,54 @@ BlitzMax: - .bmx aliases: - bmax + ace_mode: text Bluespec: type: programming extensions: - .bsv - tm_scope: source.verilog + tm_scope: source.bsv + ace_mode: verilog Boo: type: programming color: "#d4bec1" extensions: - .boo + ace_mode: text Brainfuck: extensions: - .b - .bf tm_scope: source.bf + ace_mode: text Brightscript: type: programming extensions: - .brs tm_scope: none + ace_mode: text Bro: type: programming extensions: - .bro + ace_mode: text C: type: programming color: "#555" extensions: - .c + - .C + - .H - .cats - .h - .idc - .w + ace_mode: c_cpp C#: type: programming @@ -335,11 +380,9 @@ C++: - cpp extensions: - .cpp - - .C - - .CPP - - .H - .c++ - .cc + - .cp - .cxx - .h - .h++ @@ -356,6 +399,7 @@ C-ObjDump: extensions: - .c-objdump tm_scope: objdump.x86asm + ace_mode: assembly_x86 C2hs Haskell: type: programming @@ -365,19 +409,22 @@ C2hs Haskell: extensions: - .chs tm_scope: source.haskell + ace_mode: haskell CLIPS: type: programming extensions: - .clp - tm_scope: none + tm_scope: source.clips + ace_mode: text CMake: extensions: - .cmake - - .in + - .cmake.in filenames: - CMakeLists.txt + ace_mode: text COBOL: type: programming @@ -389,8 +436,11 @@ COBOL: - .ccp - .cobol - .cpy + ace_mode: cobol CSS: + type: markup + tm_scope: source.css ace_mode: css color: "#563d7c" extensions: @@ -401,11 +451,22 @@ Cap'n Proto: tm_scope: source.capnp extensions: - .capnp + ace_mode: text + +CartoCSS: + type: programming + aliases: + - Carto + extensions: + - .mss + ace_mode: text + tm_scope: source.css.mss Ceylon: type: programming extensions: - .ceylon + ace_mode: text Chapel: type: programming @@ -414,11 +475,13 @@ Chapel: - chpl extensions: - .chpl + ace_mode: text ChucK: extensions: - .ck tm_scope: source.java + ace_mode: java Cirru: type: programming @@ -442,6 +505,7 @@ Clean: - .icl - .dcl tm_scope: none + ace_mode: text Clojure: type: programming @@ -452,10 +516,10 @@ Clojure: - .cl2 - .cljc - .cljs + - .cljs.hl - .cljscm - .cljx - .hic - - .hl filenames: - riemann.config @@ -524,6 +588,7 @@ Common Lisp: - ccl - clisp - ecl + ace_mode: lisp Component Pascal: type: programming @@ -535,12 +600,21 @@ Component Pascal: aliases: - delphi - objectpascal + ace_mode: pascal + +Cool: + type: programming + extensions: + - .cl + tm_scope: source.cool + ace_mode: text Coq: type: programming extensions: - .coq - .v + ace_mode: text Cpp-ObjDump: type: data @@ -553,13 +627,15 @@ Cpp-ObjDump: tm_scope: objdump.x86asm aliases: - c++-objdumb + ace_mode: assembly_x86 Creole: type: prose wrap: true extensions: - .creole - tm_scope: none + tm_scope: text.html.creole + ace_mode: text Crystal: type: programming @@ -576,6 +652,7 @@ Cucumber: tm_scope: text.gherkin.feature aliases: - gherkin + ace_mode: text Cuda: type: programming @@ -583,12 +660,14 @@ Cuda: - .cu - .cuh tm_scope: source.cuda-c++ + ace_mode: c_cpp Cycript: type: programming extensions: - .cy tm_scope: source.js + ace_mode: javascript Cython: type: programming @@ -599,6 +678,7 @@ Cython: - .pxi aliases: - pyrex + ace_mode: text D: type: programming @@ -606,12 +686,14 @@ D: extensions: - .d - .di + ace_mode: d D-ObjDump: type: data extensions: - .d-objdump tm_scope: objdump.x86asm + ace_mode: assembly_x86 DM: type: programming @@ -621,6 +703,7 @@ DM: aliases: - byond tm_scope: source.c++ + ace_mode: c_cpp Darcs Patch: search_term: dpatch @@ -630,12 +713,14 @@ Darcs Patch: - .darcspatch - .dpatch tm_scope: none + ace_mode: text Dart: type: programming color: "#98BAD6" extensions: - .dart + ace_mode: dart Diff: extensions: @@ -643,6 +728,7 @@ Diff: - .patch aliases: - udiff + ace_mode: diff Dockerfile: type: data @@ -651,6 +737,7 @@ Dockerfile: - .dockerfile filenames: - Dockerfile + ace_mode: dockerfile Dogescript: type: programming @@ -658,6 +745,7 @@ Dogescript: extensions: - .djs tm_scope: none + ace_mode: text Dylan: type: programming @@ -667,6 +755,7 @@ Dylan: - .dyl - .intr - .lid + ace_mode: text E: type: programming @@ -674,6 +763,7 @@ E: extensions: - .E tm_scope: none + ace_mode: text ECL: type: programming @@ -682,6 +772,7 @@ ECL: - .ecl - .eclxml tm_scope: none + ace_mode: text Eagle: type: markup @@ -690,6 +781,7 @@ Eagle: - .sch - .brd tm_scope: text.xml + ace_mode: xml Ecere Projects: type: data @@ -697,12 +789,14 @@ Ecere Projects: extensions: - .epj tm_scope: source.json + ace_mode: json Eiffel: type: programming color: "#946d57" extensions: - .e + ace_mode: eiffel Elixir: type: programming @@ -710,12 +804,15 @@ Elixir: extensions: - .ex - .exs + ace_mode: elixir Elm: type: programming + color: "#60B5CC" extensions: - .elm - tm_scope: source.haskell + tm_scope: source.elm + ace_mode: elm Emacs Lisp: type: programming @@ -726,9 +823,12 @@ Emacs Lisp: - emacs filenames: - .emacs + - .emacs.desktop extensions: - .el - .emacs + - .emacs.desktop + ace_mode: lisp EmberScript: type: programming @@ -737,6 +837,7 @@ EmberScript: - .em - .emberscript tm_scope: source.coffee + ace_mode: coffee Erlang: type: programming @@ -746,6 +847,7 @@ Erlang: - .es - .escript - .hrl + ace_mode: erlang interpreters: - escript @@ -760,6 +862,7 @@ F#: - .fsi - .fsx tm_scope: source.fsharp + ace_mode: text FLUX: type: programming @@ -768,6 +871,7 @@ FLUX: - .fx - .flux tm_scope: none + ace_mode: text FORTRAN: type: programming @@ -790,6 +894,7 @@ FORTRAN: - .for - .fpp tm_scope: source.fortran.modern + ace_mode: text Factor: type: programming @@ -799,6 +904,7 @@ Factor: filenames: - .factor-boot-rc - .factor-rc + ace_mode: text Fancy: type: programming @@ -808,6 +914,7 @@ Fancy: - .fancypack filenames: - Fakefile + ace_mode: text Fantom: type: programming @@ -815,18 +922,23 @@ Fantom: extensions: - .fan tm_scope: source.fan + ace_mode: text Forth: type: programming color: "#341708" extensions: - .fth + - .4TH - .4th - .F - .f - .for - .forth + - .fr - .frt + - .fs + ace_mode: forth Frege: type: programming @@ -834,6 +946,7 @@ Frege: extensions: - .fr tm_scope: source.haskell + ace_mode: haskell G-code: type: data @@ -841,13 +954,15 @@ G-code: - .g - .gco - .gcode - tm_scope: none + tm_scope: source.gcode + ace_mode: gcode GAMS: type: programming extensions: - .gms tm_scope: none + ace_mode: text GAP: type: programming @@ -856,7 +971,9 @@ GAP: - .gap - .gd - .gi - tm_scope: none + - .tst + tm_scope: source.gap + ace_mode: text GAS: type: programming @@ -865,12 +982,14 @@ GAS: - .s - .S tm_scope: source.asm.x86 + ace_mode: assembly_x86 GDScript: type: programming extensions: - .gd - tm_scope: none + tm_scope: source.gdscript + ace_mode: text GLSL: group: C @@ -880,6 +999,7 @@ GLSL: - .fp - .frag - .frg + - .fs - .fshader - .geo - .geom @@ -889,13 +1009,15 @@ GLSL: - .vert - .vrx - .vshader + ace_mode: glsl Game Maker Language: type: programming color: "#8ad353" extensions: - .gml - tm_scope: source.js + tm_scope: source.c++ + ace_mode: c_cpp Genshi: extensions: @@ -904,18 +1026,21 @@ Genshi: aliases: - xml+genshi - xml+kid + ace_mode: xml Gentoo Ebuild: group: Shell extensions: - .ebuild tm_scope: source.shell + ace_mode: sh Gentoo Eclass: group: Shell extensions: - .eclass tm_scope: source.shell + ace_mode: sh Gettext Catalog: search_term: pot @@ -926,6 +1051,7 @@ Gettext Catalog: - .po - .pot tm_scope: source.po + ace_mode: text Glyph: type: programming @@ -933,6 +1059,7 @@ Glyph: extensions: - .glf tm_scope: source.tcl + ace_mode: tcl Gnuplot: type: programming @@ -945,19 +1072,22 @@ Gnuplot: - .plt interpreters: - gnuplot + ace_mode: text Go: type: programming color: "#375eab" extensions: - .go + ace_mode: golang Golo: type: programming color: "#f6a51f" extensions: - .golo - tm_scope: none + tm_scope: source.golo + ace_mode: text Gosu: type: programming @@ -968,12 +1098,21 @@ Gosu: - .gsx - .vark tm_scope: source.gosu.2 + ace_mode: text Grace: type: programming extensions: - .grace - tm_scope: none + tm_scope: source.grace + ace_mode: text + +Gradle: + type: data + extensions: + - .gradle + tm_scope: source.groovy.gradle + ace_mode: text Grammatical Framework: type: programming @@ -985,12 +1124,14 @@ Grammatical Framework: searchable: true color: "#ff0000" tm_scope: source.haskell + ace_mode: haskell Graph Modeling Language: type: data extensions: - .gml tm_scope: none + ace_mode: text Graphviz (DOT): type: data @@ -999,6 +1140,7 @@ Graphviz (DOT): - .dot - .DOT - .gv + ace_mode: text Groff: extensions: @@ -1013,6 +1155,7 @@ Groff: tm_scope: text.groff aliases: - nroff + ace_mode: text Groovy: type: programming @@ -1034,16 +1177,19 @@ Groovy Server Pages: extensions: - .gsp tm_scope: text.html.jsp + ace_mode: jsp HTML: type: markup tm_scope: text.html.basic ace_mode: html + color: "#e44b23" aliases: - xhtml extensions: - .html - .htm + - .html.hl - .st - .xht - .xhtml @@ -1059,6 +1205,7 @@ HTML+Django: - html+django/jinja - html+jinja - htmldjango + ace_mode: django HTML+ERB: type: markup @@ -1068,7 +1215,8 @@ HTML+ERB: - erb extensions: - .erb - - .deface + - .erb.deface + ace_mode: html_ruby HTML+PHP: type: markup @@ -1076,12 +1224,14 @@ HTML+PHP: group: HTML extensions: - .phtml + ace_mode: php HTTP: type: data extensions: - .http - tm_scope: none + tm_scope: source.httpspec + ace_mode: text Hack: type: programming @@ -1089,23 +1239,26 @@ Hack: extensions: - .hh - .php - tm_scope: none + tm_scope: text.html.php Haml: group: HTML type: markup extensions: - .haml - - .deface + - .haml.deface + ace_mode: haml Handlebars: type: markup aliases: - hbs + - htmlbars extensions: - .handlebars - .hbs tm_scope: text.html.handlebars + ace_mode: handlebars Harbour: type: programming @@ -1113,6 +1266,7 @@ Harbour: extensions: - .hb tm_scope: none + ace_mode: text Haskell: type: programming @@ -1120,6 +1274,7 @@ Haskell: extensions: - .hs - .hsc + ace_mode: haskell Haxe: type: programming @@ -1132,13 +1287,13 @@ Haxe: Hy: type: programming - ace_mode: clojure + ace_mode: text color: "#7891b1" extensions: - .hy aliases: - hylang - tm_scope: none + tm_scope: source.hy IDL: type: programming @@ -1146,6 +1301,7 @@ IDL: extensions: - .pro - .dlm + ace_mode: text IGOR Pro: type: programming @@ -1155,6 +1311,7 @@ IGOR Pro: - igor - igorpro tm_scope: none + ace_mode: text INI: type: data @@ -1166,6 +1323,7 @@ INI: tm_scope: source.ini aliases: - dosini + ace_mode: ini IRC log: search_term: irc @@ -1176,12 +1334,14 @@ IRC log: - .irclog - .weechatlog tm_scope: none + ace_mode: text Idris: type: programming extensions: - .idr - .lidr + ace_mode: text Inform 7: type: programming @@ -1193,17 +1353,20 @@ Inform 7: aliases: - i7 - inform7 + ace_mode: text Inno Setup: extensions: - .iss - tm_scope: none + tm_scope: source.inno + ace_mode: text Io: type: programming color: "#a9188d" extensions: - .io + ace_mode: io Ioke: type: programming @@ -1212,19 +1375,22 @@ Ioke: - .ik interpreters: - ioke + ace_mode: text Isabelle: type: programming color: "#fdcd00" extensions: - .thy - tm_scope: none + tm_scope: source.isabelle.theory + ace_mode: text J: type: programming extensions: - .ijs - tm_scope: none + tm_scope: source.j + ace_mode: text JSON: type: data @@ -1235,13 +1401,6 @@ JSON: extensions: - .json - .lock - - .sublime-keymap - - .sublime-mousemap - - .sublime-project - - .sublime-settings - - .sublime-workspace - - .sublime_metrics - - .sublime_session filenames: - .jshintrc - composer.lock @@ -1251,11 +1410,12 @@ JSON5: extensions: - .json5 tm_scope: source.js + ace_mode: javascript JSONLD: type: data group: JavaScript - ace_mode: json + ace_mode: javascript extensions: - .jsonld tm_scope: source.js @@ -1273,6 +1433,14 @@ Jade: extensions: - .jade tm_scope: source.jade + ace_mode: jade + +Jasmin: + type: programming + ace_mode: java + extensions: + - .j + tm_scope: source.jasmin Java: type: programming @@ -1289,6 +1457,7 @@ Java Server Pages: extensions: - .jsp tm_scope: text.html.jsp + ace_mode: jsp JavaScript: type: programming @@ -1304,6 +1473,7 @@ JavaScript: - .bones - .es6 - .frag + - .gs - .jake - .jsb - .jsfl @@ -1314,6 +1484,19 @@ JavaScript: - .pac - .sjs - .ssjs + - .sublime-build + - .sublime-commands + - .sublime-completions + - .sublime-keymap + - .sublime-macro + - .sublime-menu + - .sublime-mousemap + - .sublime-project + - .sublime-settings + - .sublime-theme + - .sublime-workspace + - .sublime_metrics + - .sublime_session - .xsjs - .xsjslib filenames: @@ -1326,6 +1509,7 @@ Julia: extensions: - .jl color: "#a270ba" + ace_mode: julia KRL: type: programming @@ -1333,6 +1517,7 @@ KRL: extensions: - .krl tm_scope: none + ace_mode: text Kit: type: markup @@ -1348,6 +1533,7 @@ Kotlin: - .ktm - .kts tm_scope: source.Kotlin + ace_mode: text LFE: type: programming @@ -1356,10 +1542,12 @@ LFE: color: "#004200" group: Erlang tm_scope: source.lisp + ace_mode: lisp LLVM: extensions: - .ll + ace_mode: text LOLCODE: type: programming @@ -1367,6 +1555,7 @@ LOLCODE: - .lol color: "#cc9900" tm_scope: none + ace_mode: text LSL: type: programming @@ -1382,6 +1571,7 @@ LabVIEW: extensions: - .lvproj tm_scope: none + ace_mode: text Lasso: type: programming @@ -1395,6 +1585,7 @@ Lasso: tm_scope: file.lasso aliases: - lassoscript + ace_mode: text Latte: type: markup @@ -1403,6 +1594,7 @@ Latte: extensions: - .latte tm_scope: source.smarty + ace_mode: smarty Less: type: markup @@ -1410,17 +1602,20 @@ Less: extensions: - .less tm_scope: source.css.less + ace_mode: less LilyPond: extensions: - .ly - .ily + ace_mode: text Liquid: type: markup extensions: - .liquid - tm_scope: none + tm_scope: text.html.liquid + ace_mode: liquid Literate Agda: type: programming @@ -1428,6 +1623,7 @@ Literate Agda: extensions: - .lagda tm_scope: none + ace_mode: text Literate CoffeeScript: type: programming @@ -1440,6 +1636,7 @@ Literate CoffeeScript: - litcoffee extensions: - .litcoffee + ace_mode: text Literate Haskell: type: programming @@ -1451,10 +1648,10 @@ Literate Haskell: extensions: - .lhs tm_scope: text.tex.latex.haskell + ace_mode: text LiveScript: type: programming - ace_mode: ls color: "#499886" aliases: - live-script @@ -1464,6 +1661,7 @@ LiveScript: - ._ls filenames: - Slakefile + ace_mode: livescript Logos: type: programming @@ -1471,12 +1669,14 @@ Logos: - .xm - .x - .xi + ace_mode: text Logtalk: type: programming extensions: - .lgt - .logtalk + ace_mode: text LookML: type: programming @@ -1486,6 +1686,13 @@ LookML: - .lookml tm_scope: source.yaml +LoomScript: + type: programming + extensions: + - .ls + tm_scope: source.loomscript + ace_mode: text + Lua: type: programming ace_mode: lua @@ -1508,6 +1715,7 @@ M: - .mumps - .m tm_scope: source.lisp + ace_mode: lisp MTML: type: markup @@ -1515,6 +1723,7 @@ MTML: extensions: - .mtml tm_scope: text.html.basic + ace_mode: html Makefile: type: programming @@ -1531,12 +1740,14 @@ Makefile: - makefile interpreters: - make + ace_mode: makefile Mako: extensions: - .mako - .mao tm_scope: text.html.mako + ace_mode: text Markdown: type: prose @@ -1549,15 +1760,15 @@ Markdown: - .mkdn - .mkdown - .ron - tm_scope: text.html.markdown + tm_scope: source.gfm Mask: type: markup color: "#f97732" - ace_mode: scss + ace_mode: mask extensions: - .mask - tm_scope: source.scss + tm_scope: source.mask Mathematica: type: programming @@ -1570,6 +1781,7 @@ Mathematica: - .nbp aliases: - mma + ace_mode: text Matlab: type: programming @@ -1577,12 +1789,14 @@ Matlab: extensions: - .matlab - .m + ace_mode: matlab Maven POM: type: data tm_scope: text.xml.pom filenames: - pom.xml + ace_mode: xml Max: type: programming @@ -1598,28 +1812,34 @@ Max: - .mxt - .pat tm_scope: source.json + ace_mode: json MediaWiki: type: prose wrap: true extensions: - .mediawiki - tm_scope: none + tm_scope: text.html.mediawiki + ace_mode: text Mercury: type: programming color: "#abcdef" ace_mode: prolog + interpreters: + - mmi extensions: - .m - .moo - tm_scope: source.prolog + tm_scope: source.mercury + ace_mode: prolog MiniD: # Legacy searchable: false extensions: - .minid # Dummy extension tm_scope: none + ace_mode: text Mirah: type: programming @@ -1631,17 +1851,27 @@ Mirah: - .mir - .mirah tm_scope: source.ruby + ace_mode: ruby + +Modelica: + type: programming + extensions: + - .mo + tm_scope: source.modelica + ace_mode: text Monkey: type: programming extensions: - .monkey + ace_mode: text Moocode: type: programming extensions: - .moo tm_scope: none + ace_mode: text MoonScript: type: programming @@ -1649,22 +1879,26 @@ MoonScript: - .moon interpreters: - moon + ace_mode: text Myghty: extensions: - .myt tm_scope: none + ace_mode: text NSIS: extensions: - .nsi - .nsh + ace_mode: text Nemerle: type: programming color: "#0d3c6e" extensions: - .n + ace_mode: text NetLogo: type: programming @@ -1672,6 +1906,20 @@ NetLogo: extensions: - .nlogo tm_scope: source.lisp + ace_mode: lisp + +NewLisp: + type: programming + lexer: NewLisp + color: "#eedd66" + extensions: + - .nl + - .lisp + - .lsp + interpreters: + - newlisp + tm_scope: source.lisp + ace_mode: lisp Nginx: type: markup @@ -1680,6 +1928,7 @@ Nginx: tm_scope: source.nginx aliases: - nginx configuration file + ace_mode: text Nimrod: type: programming @@ -1687,27 +1936,33 @@ Nimrod: extensions: - .nim - .nimrod + ace_mode: text + tm_scope: source.nim Ninja: type: data tm_scope: source.ninja extensions: - .ninja + ace_mode: text Nit: type: programming color: "#0d8921" extensions: - .nit - tm_scope: none + tm_scope: source.nit + ace_mode: text Nix: type: programming + color: "#7070ff" extensions: - .nix aliases: - nixos - tm_scope: none + tm_scope: source.nix + ace_mode: nix Nu: type: programming @@ -1719,6 +1974,7 @@ Nu: filenames: - Nukefile tm_scope: source.scheme + ace_mode: scheme interpreters: - nush @@ -1729,6 +1985,7 @@ NumPy: - .numpyw - .numsc tm_scope: none + ace_mode: text OCaml: type: programming @@ -1748,6 +2005,7 @@ ObjDump: extensions: - .objdump tm_scope: objdump.x86asm + ace_mode: assembly_x86 Objective-C: type: programming @@ -1760,6 +2018,7 @@ Objective-C: extensions: - .m - .h + ace_mode: objectivec Objective-C++: type: programming @@ -1771,6 +2030,7 @@ Objective-C++: - objectivec++ extensions: - .mm + ace_mode: objectivec Objective-J: type: programming @@ -1783,6 +2043,7 @@ Objective-J: - .j - .sj tm_scope: source.js.objj + ace_mode: text Omgrofl: type: programming @@ -1790,18 +2051,21 @@ Omgrofl: - .omgrofl color: "#cabbff" tm_scope: none + ace_mode: text Opa: type: programming extensions: - .opa + ace_mode: text Opal: type: programming color: "#f7ede0" extensions: - .opal - tm_scope: none + tm_scope: source.opal + ace_mode: text OpenCL: type: programming @@ -1810,6 +2074,7 @@ OpenCL: - .cl - .opencl tm_scope: source.c + ace_mode: c_cpp OpenEdge ABL: type: programming @@ -1821,12 +2086,14 @@ OpenEdge ABL: - .p - .cls tm_scope: source.abl + ace_mode: text OpenSCAD: type: programming extensions: - .scad tm_scope: none + ace_mode: scad Org: type: prose @@ -1834,6 +2101,7 @@ Org: extensions: - .org tm_scope: none + ace_mode: text Ox: type: programming @@ -1841,7 +2109,8 @@ Ox: - .ox - .oxh - .oxo - tm_scope: none + tm_scope: source.ox + ace_mode: text Oxygene: type: programming @@ -1849,6 +2118,15 @@ Oxygene: extensions: - .oxygene tm_scope: none + ace_mode: text + +Oz: + type: programming + color: "#fcaf3e" + extensions: + - .oz + tm_scope: source.oz + ace_mode: text PAWN: type: programming @@ -1856,6 +2134,7 @@ PAWN: extensions: - .pwn tm_scope: source.c++ + ace_mode: c_cpp PHP: type: programming @@ -1867,7 +2146,6 @@ PHP: - .aw - .ctp - .fcgi - - .module - .php3 - .php4 - .php5 @@ -1885,13 +2163,15 @@ Pan: extensions: - .pan tm_scope: none + ace_mode: text Papyrus: type: programming color: "#6600cc" extensions: - .psc - tm_scope: none + tm_scope: source.papyrus + ace_mode: text Parrot: type: programming @@ -1899,6 +2179,7 @@ Parrot: extensions: - .parrot # Dummy extension tm_scope: none + ace_mode: text Parrot Assembly: group: Parrot @@ -1910,6 +2191,7 @@ Parrot Assembly: interpreters: - parrot tm_scope: none + ace_mode: text Parrot Internal Representation: group: Parrot @@ -1921,6 +2203,7 @@ Parrot Internal Representation: - .pir interpreters: - parrot + ace_mode: text Pascal: type: programming @@ -1931,6 +2214,7 @@ Pascal: - .dpr - .lpr - .pp + ace_mode: pascal Perl: type: programming @@ -1955,17 +2239,23 @@ Perl6: type: programming color: "#0298c3" extensions: - - .p6 - .6pl - .6pm - .nqp + - .p6 - .p6l - .p6m + - .pl - .pl6 + - .pm - .pm6 + - .t + filenames: + - Rexfile interpreters: - perl6 tm_scope: none + ace_mode: perl PigLatin: type: programming @@ -1973,6 +2263,7 @@ PigLatin: extensions: - .pig tm_scope: none + ace_mode: text Pike: type: programming @@ -1980,6 +2271,9 @@ Pike: extensions: - .pike - .pmod + interpreters: + - pike + ace_mode: text Pod: type: prose @@ -1994,7 +2288,8 @@ PogoScript: color: "#d80074" extensions: - .pogo - tm_scope: none + tm_scope: source.pogoscript + ace_mode: text PostScript: type: markup @@ -2004,6 +2299,7 @@ PostScript: tm_scope: source.postscript aliases: - postscr + ace_mode: text PowerShell: type: programming @@ -2020,6 +2316,7 @@ Processing: color: "#2779ab" extensions: - .pde + ace_mode: text Prolog: type: programming @@ -2031,13 +2328,15 @@ Prolog: - .prolog interpreters: - swipl + ace_mode: prolog Propeller Spin: type: programming color: "#2b446d" extensions: - .spin - tm_scope: none + tm_scope: source.spin + ace_mode: text Protocol Buffer: type: markup @@ -2047,6 +2346,15 @@ Protocol Buffer: extensions: - .proto tm_scope: source.protobuf + ace_mode: protobuf + +Public Key: + type: data + extensions: + - .asc + - .pub + tm_scope: none + ace_mode: text Puppet: type: programming @@ -2055,6 +2363,7 @@ Puppet: - .pp filenames: - Modulefile + ace_mode: text Pure Data: type: programming @@ -2062,6 +2371,16 @@ Pure Data: extensions: - .pd tm_scope: none + ace_mode: text + +PureBasic: + type: programming + color: "#5a6986" + extensions: + - .pb + - .pbi + tm_scope: none + ace_mode: text PureScript: type: programming @@ -2069,6 +2388,7 @@ PureScript: extensions: - .purs tm_scope: source.haskell + ace_mode: haskell Python: type: programming @@ -2091,11 +2411,14 @@ Python: - BUILD - SConscript - SConstruct + - Snakefile - wscript interpreters: - python - python2 - python3 + aliases: + - rusthon Python traceback: type: data @@ -2104,6 +2427,7 @@ Python traceback: extensions: - .pytb tm_scope: text.python.traceback + ace_mode: text QML: type: markup @@ -2111,6 +2435,7 @@ QML: extensions: - .qml tm_scope: source.qml + ace_mode: text QMake: extensions: @@ -2118,6 +2443,7 @@ QMake: - .pri interpreters: - qmake + ace_mode: text R: type: programming @@ -2136,6 +2462,15 @@ R: - .Rprofile interpreters: - Rscript + ace_mode: r + +RAML: + type: data + ace_mode: yaml + tm_scope: source.yaml + color: "#77d9fb" + extensions: + - .raml RDoc: type: prose @@ -2155,6 +2490,7 @@ REALbasic: - .rbtbar - .rbuistate tm_scope: source.vbnet + ace_mode: text RHTML: type: markup @@ -2164,6 +2500,7 @@ RHTML: tm_scope: text.html.erb aliases: - html+ruby + ace_mode: rhtml RMarkdown: type: prose @@ -2183,6 +2520,7 @@ Racket: - .rktl - .scrbl tm_scope: source.racket + ace_mode: lisp Ragel in Ruby Host: type: programming @@ -2193,6 +2531,7 @@ Ragel in Ruby Host: - ragel-rb - ragel-ruby tm_scope: none + ace_mode: text Raw token data: search_term: raw @@ -2201,6 +2540,7 @@ Raw token data: extensions: - .raw tm_scope: none + ace_mode: text Rebol: type: programming @@ -2211,6 +2551,7 @@ Rebol: - .r2 - .r3 - .rebol + ace_mode: text Red: type: programming @@ -2221,11 +2562,13 @@ Red: aliases: - red/system tm_scope: none + ace_mode: text Redcode: extensions: - .cw tm_scope: none + ace_mode: text RobotFramework: type: programming @@ -2233,6 +2576,7 @@ RobotFramework: - .robot # - .txt tm_scope: text.robot + ace_mode: text Rouge: type: programming @@ -2295,13 +2639,15 @@ Rust: color: "#dea584" extensions: - .rs + ace_mode: rust SAS: type: programming color: "#1E90FF" extensions: - .sas - tm_scope: none + tm_scope: source.sas + ace_mode: text SCSS: type: markup @@ -2311,6 +2657,14 @@ SCSS: extensions: - .scss +SPARQL: + type: data + tm_scope: source.sparql + ace_mode: text + extensions: + - .sparql + - .rq + SQF: type: programming color: "#FFCB1F" @@ -2318,6 +2672,7 @@ SQF: - .sqf - .hqf tm_scope: source.sqf + ace_mode: text SQL: type: data @@ -2325,6 +2680,8 @@ SQL: ace_mode: sql extensions: - .sql + - .cql + - .ddl - .prc - .tab - .udf @@ -2335,14 +2692,35 @@ STON: group: Smalltalk extensions: - .ston - tm_scope: source.json + tm_scope: source.smalltalk + ace_mode: text + +SVG: + type: data + extensions: + - .svg + tm_scope: text.xml + ace_mode: xml Sage: type: programming group: Python extensions: - .sage + - .sagews tm_scope: source.python + ace_mode: python + +SaltStack: + type: data + group: YAML + aliases: + - saltstate + - salt + extensions: + - .sls + tm_scope: source.yaml.salt + ace_mode: yaml Sass: type: markup @@ -2350,7 +2728,7 @@ Sass: group: CSS extensions: - .sass - - .scss + ace_mode: sass Scala: type: programming @@ -2369,6 +2747,7 @@ Scaml: extensions: - .scaml tm_scope: source.scaml + ace_mode: text Scheme: type: programming @@ -2384,6 +2763,7 @@ Scheme: - racket - bigloo - chicken + ace_mode: scheme Scilab: type: programming @@ -2391,6 +2771,7 @@ Scilab: - .sci - .sce - .tst + ace_mode: text Self: type: programming @@ -2398,6 +2779,7 @@ Self: extensions: - .self tm_scope: none + ace_mode: text Shell: type: programming @@ -2419,8 +2801,10 @@ Shell: - .zsh interpreters: - bash + - rc - sh - zsh + ace_mode: sh ShellSession: type: programming @@ -2430,6 +2814,7 @@ ShellSession: - bash session - console tm_scope: text.shell-session + ace_mode: sh Shen: type: programming @@ -2437,6 +2822,7 @@ Shen: extensions: - .shen tm_scope: none + ace_mode: text Slash: type: programming @@ -2444,6 +2830,7 @@ Slash: extensions: - .sl tm_scope: text.html.slash + ace_mode: text Slim: group: HTML @@ -2451,18 +2838,22 @@ Slim: color: "#ff8877" extensions: - .slim + ace_mode: text Smalltalk: type: programming color: "#596706" extensions: - .st + - .cs aliases: - squeak + ace_mode: text Smarty: extensions: - .tpl + ace_mode: smarty SourcePawn: type: programming @@ -2472,12 +2863,14 @@ SourcePawn: extensions: - .sp tm_scope: source.sp + ace_mode: text Squirrel: type: programming extensions: - .nut tm_scope: source.c++ + ace_mode: c_cpp Standard ML: type: programming @@ -2490,6 +2883,7 @@ Standard ML: - .sig - .sml tm_scope: source.ml + ace_mode: text Stata: type: programming @@ -2501,6 +2895,7 @@ Stata: - .mata - .matah - .sthlp + ace_mode: text Stylus: type: markup @@ -2508,6 +2903,7 @@ Stylus: extensions: - .styl tm_scope: none + ace_mode: stylus SuperCollider: type: programming @@ -2516,12 +2912,14 @@ SuperCollider: - .scd - .sc tm_scope: none + ace_mode: text Swift: type: programming color: "#ffac45" extensions: - .swift + ace_mode: text SystemVerilog: type: programming @@ -2530,18 +2928,21 @@ SystemVerilog: - .sv - .svh - .vh + ace_mode: verilog TOML: type: data extensions: - .toml tm_scope: source.toml + ace_mode: toml TXL: type: programming extensions: - .txl - tm_scope: none + tm_scope: source.txl + ace_mode: text Tcl: type: programming @@ -2553,6 +2954,7 @@ Tcl: interpreters: - tclsh - wish + ace_mode: tcl Tcsh: type: programming @@ -2561,11 +2963,12 @@ Tcsh: - .tcsh - .csh tm_scope: source.shell + ace_mode: sh TeX: type: markup color: "#3D6117" - ace_mode: latex + ace_mode: tex wrap: true aliases: - latex @@ -2591,6 +2994,16 @@ Tea: extensions: - .tea tm_scope: source.tea + ace_mode: text + +Text: + type: prose + wrap: true + extensions: + - .txt + - .fr + tm_scope: none + ace_mode: text Textile: type: prose @@ -2605,6 +3018,7 @@ Thrift: tm_scope: source.thrift extensions: - .thrift + ace_mode: text Turing: type: programming @@ -2613,6 +3027,14 @@ Turing: - .t - .tu tm_scope: none + ace_mode: text + +Turtle: + type: data + extensions: + - .ttl + tm_scope: source.turtle + ace_mode: text Twig: type: markup @@ -2620,6 +3042,7 @@ Twig: extensions: - .twig tm_scope: text.html.twig + ace_mode: twig TypeScript: type: programming @@ -2629,6 +3052,7 @@ TypeScript: extensions: - .ts tm_scope: source.ts + ace_mode: typescript Unified Parallel C: type: programming @@ -2645,6 +3069,7 @@ UnrealScript: extensions: - .uc tm_scope: source.java + ace_mode: java VCL: type: programming @@ -2666,6 +3091,7 @@ VHDL: - .vhs - .vht - .vhw + ace_mode: vhdl Vala: type: programming @@ -2673,6 +3099,7 @@ Vala: extensions: - .vala - .vapi + ace_mode: vala Verilog: type: programming @@ -2680,6 +3107,7 @@ Verilog: extensions: - .v - .veo + ace_mode: verilog VimL: type: programming @@ -2694,6 +3122,7 @@ VimL: - _vimrc - gvimrc - vimrc + ace_mode: text Visual Basic: type: programming @@ -2711,6 +3140,7 @@ Visual Basic: aliases: - vb.net - vbnet + ace_mode: text Volt: type: programming @@ -2718,12 +3148,29 @@ Volt: extensions: - .volt tm_scope: source.d + ace_mode: d + +Web Ontology Language: + type: markup + color: "#3994bc" + extensions: + - .owl + tm_scope: text.xml + ace_mode: xml + +WebIDL: + type: programming + extensions: + - .webidl + tm_scope: source.webidl + ace_mode: text XC: type: programming extensions: - .xc tm_scope: source.c + ace_mode: c_cpp XML: type: markup @@ -2744,14 +3191,17 @@ XML: - .dita - .ditamap - .ditaval + - .dll.config - .filters - .fsproj + - .fxml - .glade - .grxml - .ivy - .jelly - .kml - .launch + - .mm - .mxml - .nproj - .nuspec @@ -2765,7 +3215,8 @@ XML: - .rss - .scxml - .srdf - - .svg + - .stTheme + - .sublime-snippet - .targets - .tmCommand - .tmLanguage @@ -2773,6 +3224,7 @@ XML: - .tmSnippet - .tmTheme - .tml + - .ts - .ui - .urdf - .vbproj @@ -2789,18 +3241,18 @@ XML: - .xlf - .xliff - .xmi + - .xml.dist - .xsd - .xul - .zcml filenames: - .classpath - .project + - Settings.StyleCop - Web.Debug.config - Web.Release.config - Web.config - - build.xml.dist - packages.config - - phpunit.xml.dist XProc: type: programming @@ -2808,6 +3260,7 @@ XProc: - .xpl - .xproc tm_scope: text.xml + ace_mode: xml XQuery: type: programming @@ -2818,11 +3271,13 @@ XQuery: - .xql - .xqm - .xqy + ace_mode: xquery XS: extensions: - .xs tm_scope: source.c + ace_mode: c_cpp XSLT: type: programming @@ -2832,6 +3287,7 @@ XSLT: - .xslt - .xsl tm_scope: text.xml.xsl + ace_mode: xml Xojo: type: programming @@ -2843,11 +3299,13 @@ Xojo: - .xojo_toolbar - .xojo_window tm_scope: source.vbnet + ace_mode: text Xtend: type: programming extensions: - .xtend + ace_mode: text YAML: type: data @@ -2859,6 +3317,7 @@ YAML: - .reek - .rviz - .yaml + ace_mode: yaml Zephir: type: programming @@ -2866,6 +3325,7 @@ Zephir: extensions: - .zep tm_scope: source.php.zephir + ace_mode: php Zimpl: type: programming @@ -2874,6 +3334,15 @@ Zimpl: - .zmpl - .zpl tm_scope: none + ace_mode: text + +desktop: + type: data + extensions: + - .desktop + - .desktop.in + tm_scope: source.desktop + ace_mode: text eC: type: programming @@ -2881,7 +3350,8 @@ eC: extensions: - .ec - .eh - tm_scope: none + tm_scope: source.c.ec + ace_mode: text edn: type: data @@ -2896,23 +3366,27 @@ fish: group: Shell extensions: - .fish - tm_scope: none + tm_scope: source.fish + ace_mode: text mupad: extensions: - .mu + ace_mode: text nesC: type: programming color: "#ffce3b" extensions: - .nc + ace_mode: text ooc: type: programming color: "#b0b77e" extensions: - .ooc + ace_mode: text reStructuredText: type: prose @@ -2923,6 +3397,7 @@ reStructuredText: extensions: - .rst - .rest + ace_mode: text wisp: type: programming @@ -2938,3 +3413,4 @@ xBase: extensions: - .prg tm_scope: none + ace_mode: text diff --git a/lib/linguist/lazy_blob.rb b/lib/linguist/lazy_blob.rb index 9691bca5..5465a71f 100644 --- a/lib/linguist/lazy_blob.rb +++ b/lib/linguist/lazy_blob.rb @@ -4,7 +4,7 @@ require 'rugged' module Linguist class LazyBlob - GIT_ATTR = ['linguist-language', 'linguist-vendored'] + GIT_ATTR = ['linguist-documentation', 'linguist-language', 'linguist-vendored'] GIT_ATTR_OPTS = { :priority => [:index], :skip_system => true } GIT_ATTR_FLAGS = Rugged::Repository::Attributes.parse_opts(GIT_ATTR_OPTS) @@ -37,6 +37,14 @@ module Linguist end end + def documentation? + if attr = git_attributes['linguist-documentation'] + boolean_attribute(attr) + else + super + end + end + def language return @language if defined?(@language) diff --git a/lib/linguist/popular.yml b/lib/linguist/popular.yml index 68d9d0b8..1a5cb750 100644 --- a/lib/linguist/popular.yml +++ b/lib/linguist/popular.yml @@ -3,7 +3,6 @@ # This file should only be edited by GitHub staff - ActionScript -- Bash - C - C# - C++ @@ -27,3 +26,4 @@ - SQL - Scala - Scheme +- Shell diff --git a/lib/linguist/repository.rb b/lib/linguist/repository.rb index 41e829c5..895a3754 100644 --- a/lib/linguist/repository.rb +++ b/lib/linguist/repository.rb @@ -156,13 +156,8 @@ module Linguist blob = Linguist::LazyBlob.new(repository, delta.new_file[:oid], new, mode.to_s(8)) - # Skip vendored or generated blobs - next if blob.vendored? || blob.generated? || blob.language.nil? - - # Only include programming languages and acceptable markup languages - if blob.language.type == :programming || Language.detectable_markup.include?(blob.language.name) - file_map[new] = [blob.language.group.name, blob.size] - end + next unless blob.include_in_language_stats? + file_map[new] = [blob.language.group.name, blob.size] end end diff --git a/lib/linguist/samples.rb b/lib/linguist/samples.rb index 001204b5..efcba365 100644 --- a/lib/linguist/samples.rb +++ b/lib/linguist/samples.rb @@ -6,6 +6,7 @@ end require 'linguist/md5' require 'linguist/classifier' +require 'linguist/shebang' module Linguist # Model for accessing classifier training data. @@ -33,10 +34,6 @@ module Linguist Dir.entries(ROOT).sort!.each do |category| next if category == '.' || category == '..' - # Skip text and binary for now - # Possibly reconsider this later - next if category == 'Text' || category == 'Binary' - dirname = File.join(ROOT, category) Dir.entries(dirname).each do |filename| next if filename == '.' || filename == '..' @@ -61,7 +58,7 @@ module Linguist yield({ :path => path, :language => category, - :interpreter => Linguist.interpreter_from_shebang(File.read(path)), + :interpreter => Shebang.interpreter(File.read(path)), :extname => File.extname(filename) }) end @@ -114,41 +111,4 @@ module Linguist db end end - - # Used to retrieve the interpreter from the shebang line of a file's - # data. - def self.interpreter_from_shebang(data) - lines = data.lines.to_a - - if lines.any? && (match = lines[0].match(/(.+)\n?/)) && (bang = match[0]) =~ /^#!/ - bang.sub!(/^#! /, '#!') - tokens = bang.split(' ') - pieces = tokens.first.split('/') - - if pieces.size > 1 - script = pieces.last - else - script = pieces.first.sub('#!', '') - end - - script = script == 'env' ? tokens[1] : script - - # If script has an invalid shebang, we might get here - return unless script - - # "python2.6" -> "python2" - script.sub! $1, '' if script =~ /(\.\d+)$/ - - # Check for multiline shebang hacks that call `exec` - if script == 'sh' && - lines[0...5].any? { |l| l.match(/exec (\w+).+\$0.+\$@/) } - script = $1 - end - - File.basename(script) - else - nil - end - end - end diff --git a/lib/linguist/shebang.rb b/lib/linguist/shebang.rb new file mode 100644 index 00000000..6f04e866 --- /dev/null +++ b/lib/linguist/shebang.rb @@ -0,0 +1,53 @@ +module Linguist + class Shebang + # Public: Use shebang to detect language of the blob. + # + # blob - An object that quacks like a blob. + # + # Examples + # + # Shebang.call(FileBlob.new("path/to/file")) + # + # Returns an Array with one Language if the blob has a shebang with a valid + # interpreter, or empty if there is no shebang. + def self.call(blob, _ = nil) + Language.find_by_interpreter interpreter(blob.data) + end + + # Public: Get the interpreter from the shebang + # + # Returns a String or nil + def self.interpreter(data) + shebang = data.lines.first + + # First line must start with #! + return unless shebang && shebang.start_with?("#!") + + # Get the parts of the shebang without the #! + tokens = shebang.sub(/^#!\s*/, '').strip.split(' ') + + # There was nothing after the #! + return if tokens.empty? + + # Get the name of the interpreter + script = File.basename(tokens.first) + + # Get next argument if interpreter was /usr/bin/env + script = tokens[1] if script == 'env' + + # Interpreter was /usr/bin/env with no arguments + return unless script + + # "python2.6" -> "python2" + script.sub! /(\.\d+)$/, '' + + # Check for multiline shebang hacks that call `exec` + if script == 'sh' && + data.lines.first(5).any? { |l| l.match(/exec (\w+).+\$0.+\$@/) } + script = $1 + end + + File.basename(script) + end + end +end diff --git a/lib/linguist/strategy/filename.rb b/lib/linguist/strategy/filename.rb new file mode 100644 index 00000000..e682863b --- /dev/null +++ b/lib/linguist/strategy/filename.rb @@ -0,0 +1,20 @@ +module Linguist + module Strategy + # Detects language based on filename and/or extension + class Filename + def self.call(blob, _) + name = blob.name.to_s + + # A bit of an elegant hack. If the file is executable but extensionless, + # append a "magic" extension so it can be classified with other + # languages that have shebang scripts. + extensions = FileBlob.new(name).extensions + if extensions.empty? && blob.mode && (blob.mode.to_i(8) & 05) == 05 + name += ".script!" + end + + Language.find_by_filename(name) + end + end + end +end diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb new file mode 100644 index 00000000..e77597f4 --- /dev/null +++ b/lib/linguist/strategy/modeline.rb @@ -0,0 +1,30 @@ +module Linguist + module Strategy + class Modeline + EmacsModeline = /-\*-\s*mode:\s*(\w+);?\s*-\*-/i + VimModeline = /\/\*\s*vim:\s*set\s*(?:ft|filetype)=(\w+):\s*\*\//i + + # Public: Detects language based on Vim and Emacs modelines + # + # blob - An object that quacks like a blob. + # + # Examples + # + # Modeline.call(FileBlob.new("path/to/file")) + # + # Returns an Array with one Language if the blob has a Vim or Emacs modeline + # that matches a Language name or alias. Returns an empty array if no match. + def self.call(blob, _ = nil) + Array(Language.find_by_alias(modeline(blob.data))) + end + + # Public: Get the modeline from the first n-lines of the file + # + # Returns a String or nil + def self.modeline(data) + match = data.match(EmacsModeline) || data.match(VimModeline) + match[1] if match + end + end + end +end diff --git a/lib/linguist/tokenizer.rb b/lib/linguist/tokenizer.rb index 4b2ea607..05882649 100644 --- a/lib/linguist/tokenizer.rb +++ b/lib/linguist/tokenizer.rb @@ -33,7 +33,8 @@ module Linguist [''], # XML ['{-', '-}'], # Haskell ['(*', '*)'], # Coq - ['"""', '"""'] # Python + ['"""', '"""'], # Python + ["'''", "'''"] # Python ] START_SINGLE_LINE_COMMENT = Regexp.compile(SINGLE_LINE_COMMENTS.map { |c| diff --git a/lib/linguist/vendor.yml b/lib/linguist/vendor.yml index 31ff7ce7..9f6b401b 100644 --- a/lib/linguist/vendor.yml +++ b/lib/linguist/vendor.yml @@ -32,6 +32,7 @@ # Erlang bundles - ^rebar$ +- erlang.mk # Go dependencies - Godeps/_workspace/ @@ -39,24 +40,27 @@ # Minified JavaScript and CSS - (\.|-)min\.(js|css)$ +# Stylesheets imported from packages +- ([^\s]*)import\.(css|less|scss|styl)$ + # Bootstrap css and js -- (^|/)bootstrap([^.]*)\.(js|css)$ +- (^|/)bootstrap([^.]*)\.(js|css|less|scss|styl)$ +- (^|/)custom\.bootstrap([^\s]*)(js|css|less|scss|styl)$ # Font Awesome -- font-awesome.css +- (^|/)font-awesome\.(css|less|scss|styl)$ # Foundation css -- foundation.css +- (^|/)foundation\.(css|less|scss|styl)$ # Normalize.css -- normalize.css +- (^|/)normalize\.(css|less|scss|styl)$ -# Bourbon SCSS -- (^|/)[Bb]ourbon/.*\.css$ -- (^|/)[Bb]ourbon/.*\.scss$ +# Bourbon css +- (^|/)[Bb]ourbon/.*\.(css|less|scss|styl)$ # Animate.css -- animate.css +- (^|/)animate\.(css|less|scss|styl)$ # Vendored dependencies - third[-_]?party/ @@ -232,9 +236,6 @@ # .DS_Store's - .[Dd][Ss]_[Ss]tore$ -# Mercury --use-subdirs -- Mercury/ - # R packages - ^vignettes/ - ^inst/extdata/ diff --git a/lib/linguist/version.rb b/lib/linguist/version.rb index 6aa2f696..674a61b9 100644 --- a/lib/linguist/version.rb +++ b/lib/linguist/version.rb @@ -1,3 +1,3 @@ module Linguist - VERSION = "4.0.3" + VERSION = "4.4.0" end diff --git a/package.json b/package.json index acd7cd9e..025b6c1e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "repository": "https://github.com/github/linguist", "dependencies": { - "season": "~>3.0" + "season": "~>5.0" } } diff --git a/samples/ATS/main.atxt b/samples/ATS/main.atxt deleted file mode 100644 index 3bba35f0..00000000 --- a/samples/ATS/main.atxt +++ /dev/null @@ -1,215 +0,0 @@ -%{ -#include "./../ATEXT/atextfun.hats" -%} - - - - - - -EFFECTIVATS-DiningPhil2 -#patscode_style() - - - - -

-Effective ATS: Dining Philosophers -

- -In this article, I present an implementation of a slight variant of the -famous problem of 5-Dining-Philosophers by Dijkstra that makes simple but -convincing use of linear types. - -

-The Original Problem -

- -There are five philosophers sitting around a table and there are also 5 -forks placed on the table such that each fork is located between the left -hand of a philosopher and the right hand of another philosopher. Each -philosopher does the following routine repeatedly: thinking and dining. In -order to dine, a philosopher needs to first acquire two forks: one located -on his left-hand side and the other on his right-hand side. After -finishing dining, a philosopher puts the two acquired forks onto the table: -one on his left-hand side and the other on his right-hand side. - -

-A Variant of the Original Problem -

- -The following twist is added to the original version: - -

- -After a fork is used, it becomes a "dirty" fork and needs to be put in a -tray for dirty forks. There is a cleaner who cleans dirty forks and then -puts them back on the table. - -

-Channels for Communication -

- -A channel is just a shared queue of fixed capacity. The following two -functions are for inserting an element into and taking an element out of a -given channel: - -
-#pats2xhtml_sats("\
-fun{a:vt0p} channel_insert (channel (a), a): void
-fun{a:vt0p} channel_takeout (chan: channel (a)): (a) 
-")
- -If [channel_insert] is called on a channel that is full, then the caller is -blocked until an element is taken out of the channel. If [channel_takeout] -is called on a channel that is empty, then the caller is blocked until an -element is inserted into the channel. - -

-A Channel for Each Fork -

- -Forks are resources given a linear type. Each fork is initially stored in a -channel, which can be obtained by calling the following function: - -
-#pats2xhtml_sats("\
-fun fork_changet (n: nphil): channel(fork)
-")
- -where the type [nphil] is defined to be [natLt(5)] (for natural numbers -less than 5). The channels for storing forks are chosen to be of capacity -2. The reason that channels of capacity 2 are chosen to store at most one -element (in each of them) is to guarantee that these channels can never be -full (so that there is no attempt made to send signals to awake callers -supposedly being blocked due to channels being full). - - -

-A Channel for the Fork Tray -

- -A tray for storing "dirty" forks is also a channel, which can be obtained -by calling the following function: - -
-#pats2xhtml_sats("\
-fun forktray_changet ((*void*)): channel(fork)
-")
- -The capacity chosen for the channel is 6 (instead of 5) so that it can -never become full (as there are only 5 forks in total). - -

-Philosopher Loop -

- -Each philosopher is implemented as a loop: - -
-#pats2xhtml_dats('\
-implement
-phil_loop (n) = let
-//
-val () = phil_think (n)
-//
-val nl = phil_left (n) // = n
-val nr = phil_right (n) // = (n+1) % 5
-//
-val ch_lfork = fork_changet (nl)
-val ch_rfork = fork_changet (nr)
-//
-val lf = channel_takeout (ch_lfork)
-val () = println! ("phil_loop(", n, ") picks left fork")
-//
-val () = randsleep (2) // sleep up to 2 seconds
-//
-val rf = channel_takeout (ch_rfork)
-val () = println! ("phil_loop(", n, ") picks right fork")
-//
-val () = phil_dine (n, lf, rf)
-//
-val ch_forktray = forktray_changet ()
-val () = channel_insert (ch_forktray, lf) // left fork to dirty tray
-val () = channel_insert (ch_forktray, rf) // right fork to dirty tray
-//
-in
-  phil_loop (n)
-end // end of [phil_loop]
-')
- -It should be straighforward to follow the code for [phil_loop]. - -

-Fork Cleaner Loop -

- -A cleaner is implemented as a loop: - -
-#pats2xhtml_dats('\
-implement
-cleaner_loop () = let
-//
-val ch = forktray_changet ()
-val f0 = channel_takeout (ch) // [f0] is dirty
-//
-val () = cleaner_wash (f0) // washes dirty [f0]
-val () = cleaner_return (f0) // puts back cleaned [f0]
-//
-in
-  cleaner_loop ()
-end // end of [cleaner_loop]
-')
- -The function [cleaner_return] first finds out the number of a given fork -and then uses the number to locate the channel for storing the fork. Its -actual implementation is given as follows: - -
-#pats2xhtml_dats('\
-implement
-cleaner_return (f) =
-{
-  val n = fork_get_num (f)
-  val ch = fork_changet (n)
-  val () = channel_insert (ch, f)
-}
-')
- -It should now be straighforward to follow the code for [cleaner_loop]. - -

-Testing -

- -The entire code of this implementation is stored in the following files: - -
-DiningPhil2.sats
-DiningPhil2.dats
-DiningPhil2_fork.dats
-DiningPhil2_thread.dats
-
- -There is also a Makefile available for compiling the ATS source code into -an excutable for testing. One should be able to encounter a deadlock after -running the simulation for a while. - -
- -This article is written by Hongwei Xi. - - - - -%{ -implement main () = fprint_filsub (stdout_ref, "main_atxt.txt") -%} diff --git a/samples/Assembly/forth.nasm b/samples/Assembly/forth.nasm new file mode 100644 index 00000000..c411c7ff --- /dev/null +++ b/samples/Assembly/forth.nasm @@ -0,0 +1,2841 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; A Forth by Chris Hinsley +;; nasm -f macho forth.nasm +;; ld -o forth -e _main forth.o +;; ./forth +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + %define VERSION_NUM 30 + + ; various buffer area sizes + %define DATA_STACK_SIZE 1024 + %define USER_DEFS_SIZE (64*1024) + %define NUM_HASH_CHAINS 64 + %define MAX_LINE_SIZE 128 + + %define SYS_exit 1 + %define SYS_read 3 + %define SYS_write 4 + %define SYS_open 5 + %define SYS_close 6 + %define SYS_unlink 10 + %define SYS_mprotect 74 + %define SYS_fsync 95 + %define SYS_rename 128 + %define SYS_stat 188 + %define SYS_lseek 199 + %define SYS_fstat 189 + %define SYS_ftruncate 201 + + %define PROT_READ 0x01 ;pages can be read + %define PROT_WRITE 0x02 ;pages can be written + %define PROT_EXEC 0x04 ;pages can be executed + %define PROT_ALL (PROT_READ | PROT_WRITE | PROT_EXEC) + %define PAGE_SIZE 4096 + +;;;;;;;;;;;;;;;;;;;;;;;;;; +; some NASM codeing macros +;;;;;;;;;;;;;;;;;;;;;;;;;; + + %macro loopstart 0 + %push loopstart + %$loop_start: + %endmacro + + %macro break 0 + jmp %$loop_exit + %endmacro + + %macro breakif 1 + j%+1 %$loop_exit + %endmacro + + %macro loopend 0 + jmp %$loop_start + %$loop_exit: + %pop + %endmacro + + %macro repeat 0 + %push repeat + %$loop_start: + %endmacro + + %macro until 1 + j%-1 %$loop_start + %$loop_exit: + %pop + %endmacro + + %macro if 1 + %push if + j%-1 %$ifnot + %endmacro + + %macro else 0 + %ifctx if + %repl else + jmp %$ifend + %$ifnot: + %else + %error "expected `if' before `else'" + %endif + %endmacro + + %macro endif 0 + %ifctx if + %$ifnot: + %pop + %elifctx else + %$ifend: + %pop + %else + %error "expected `if' or `else' before `endif'" + %endif + %endmacro + +;;;;;;;;;;;;;;;; +; base VM macros +;;;;;;;;;;;;;;;; + + ; eip Forths IP + ; esp Forths R + ; ebp Forths S + ; ebx Forths TOS + + ; push on to return stack + %macro PUSHRSP 1 + push %1 + %endm + + ; pop top of return stack + %macro POPRSP 1 + pop %1 + %endm + + ; save into return stack + %macro PUTRSP 2 + %if (%2 = 0) + mov [esp], %1 + %elif ((%2 >= -128) && (%2 < 128)) + mov [byte esp + %2], %1 + %else + mov [long esp + %2], %1 + %endif + %endm + + ; load from return stack + %macro PICKRSP 2 + %if (%2 = 0) + mov %1, [esp] + %elif ((%2 >= -128) && (%2 < 128)) + mov %1, [byte esp + %2] + %else + mov %1, [long esp + %2] + %endif + %endm + + ; set return stack + %macro SETRSP 1 + mov esp, %1 + %endm + + ; get return stack + %macro GETRSP 1 + mov %1, esp + %endm + + ; adjust return stack + %macro ADDRSP 1 + %if ((%1 >= -128) && (%1 < 128)) + add esp, byte %1 + %else + add esp, %1 + %endif + %endm + + ; push on to data stack + %macro PUSHDSP 1 + sub ebp, byte 4 + mov [ebp], %1 + %endm + + ; pop top of data stack + %macro POPDSP 1 + mov %1, [ebp] + add ebp, byte 4 + %endm + + ; save into data stack + %macro PUTDSP 2 + %if (%2 = 0) + mov [ebp], %1 + %elif ((%2 >= -128) && (%2 < 128)) + mov [byte ebp + %2], %1 + %else + mov [long ebp + %2], %1 + %endif + %endm + + ; load from data stack + %macro PICKDSP 2 + %if (%2 = 0) + mov %1, [ebp] + %elif ((%2 >= -128) && (%2 < 128)) + mov %1, [byte ebp + %2] + %else + mov %1, [long ebp + %2] + %endif + %endm + + ; set data stack + %macro SETDSP 1 + mov ebp, %1 + %endm + + ; get data stack + %macro GETDSP 1 + mov %1, ebp + %endm + + ; adjust data stack + %macro ADDDSP 1 + %if ((%1 >= -128) && (%1 < 128)) + add ebp, byte %1 + %else + add ebp, %1 + %endif + %endm + + ; load value onto data stack + %macro LOADTOS 1 + PUSHDSP ebx + mov ebx, %1 + %endm + + ; move from data to return stack + %macro TORSP 0 + PUSHRSP ebx + POPDSP ebx + %endm + + ; move from return to data stack + %macro FROMRSP 0 + PUSHDSP ebx + POPRSP ebx + %endm + + ; copy from return to data stack + %macro FETCHRSP 0 + PUSHDSP ebx + PICKRSP ebx, 0 + %endm + + ; align reg + %define DP_ALIGN 3 + %macro ALIGNREG 1 + add %1, byte DP_ALIGN + and %1, byte ~DP_ALIGN + %endm + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; dictionary building macros +;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ; format of dictionary entry flag byte + %define F_IMMED 0x80 + %define F_HIDDEN 0x20 + %define F_LENMASK 0x1f + + %define NULL 0 + %define H_LLINK 0 + %define H_HLINK 4 + %define H_NSIZE 8 + %define H_NAME 9 + + %define XT_BODY -12 + %define XT_LENGTH -8 + %define XT_COMPILE -4 + %define XT_SIZE 12 + + %macro defword 4 + %push newword + %strlen len %1 + align 4 + dic_%3: + dd NULL ; LATEST list link + dd NULL ; hash chain link + db len + %2 ; flags + length byte + db %1 ; the name + dd %3 ; body pointer + dd %$code_end - %3 ; code length + dd %4 ; compile action word + %3: + %endm ; assembler code follows + + %macro defword_end 0 + %$code_end: + %pop + %endm + + %macro defvar 4 + defword %1, %2, %3, WORD_INLINE_COMMA + LOADTOS var_%3 + ret + defword_end + align 4 + var_%3: + dd %4 + %endm + + %macro defvar2 5 + defword %1, %2, %3, WORD_INLINE_COMMA + LOADTOS var_%3 + ret + defword_end + align 4 + var_%3: + dd %4 + dd %5 + %endm + + %macro defconst 4 + defword %1, %2, %3, WORD_INLINE_COMMA + LOADTOS %4 + ret + defword_end + %endm + +;;;;;;;;;;;;;;;;;;;;;;;;;; +; entry point +;;;;;;;;;;;;;;;;;;;;;;;;;; + + SECTION .text + global _main +_main: + ; use mprotect to allow read/write/execute of the data section + mov edx, forth_start + and edx, -PAGE_SIZE ;start address + mov ecx, forth_end + sub ecx, edx ;length + mov ebx, PROT_ALL ;flags + push ebx + push ecx + push edx + push 0 ;padding + mov eax, SYS_mprotect + int 0x80 + add esp, 16 + jmp forth_start + + SECTION .data +forth_start: + ; init data and return stacks, saving initial positions + ; in Forth vars R0 and S0 + cld + GETRSP [var_WORD_SZ] + SETDSP [var_WORD_SZ] + ADDRSP -DATA_STACK_SIZE + GETRSP [var_WORD_RZ] + + ; link built in dictionary + mov esi, dictionary_start + xor edi, edi + repeat + lodsd + mov [eax + H_LLINK], edi + mov edi, eax + push esi + mov cl, [eax + H_NSIZE] + and ecx, F_LENMASK + lea esi, [eax + H_NAME] + call strhashi + and ebx, NUM_HASH_CHAINS-1 + mov esi, hash_buckets + mov eax, [esi + (ebx * 4)] + mov [esi + (ebx * 4)], edi + mov [edi + H_HLINK], eax + pop esi + cmp esi, dictionary_end + until z + mov [var_WORD_LATEST], edi + + ; run temp interpreter loop till we can get into the real QUIT word + call WORD_LBRAC ; interpret state + LOADTOS 666q ; octal ! + TORSP + LOADTOS 0 + TORSP + LOADTOS bootfile + TORSP + call WORD_SYS_OPEN + call WORD_SYSCALL + ADDRSP 12 + TORSP ; ( fd ) of "forth.f" + loopstart + LOADTOS tib_buffer + LOADTOS MAX_LINE_SIZE + FETCHRSP ; ( c-addr len fd ) + call WORD_READLINE ; ( num flag flag ) + call WORD_DROP2 + LOADTOS tib_buffer + call WORD_SWAP + call WORD_INHASH + call WORD_STORE2 + LOADTOS 0 + call WORD_TOIN + call WORD_STORE + call WORD_INTERPRET + loopend ; and loop till QUIT takes over + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; a few case insensative string operations +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + %macro to_lower 1 + ; lower case check + cmp %1, 'A' + if ge + cmp %1, 'Z' + if le + ; make it lower case + add %1, byte 'a' - 'A' + endif + endif + %endm + +strcpyi: + test ecx, ecx + if nz + strcpyi_l1: + lodsb + to_lower al + stosb + loop strcpyi_l1 + endif + ret + +strcmpi: + test ecx, ecx + if nz + strcmpi_l1: + lodsb + mov bl, [edi] + lea edi, [edi + 1] + to_lower al + to_lower bl + cmp bl, al + if z + loop strcmpi_l1 + endif + endif + ret + +;;;;;;;;;;;;;;; +; hash function +;;;;;;;;;;;;;;; + +strhashi: + mov ebx, 5381 + test ecx, ecx + if nz + mov edx, 33 + strhashi_l1: + lodsb + movzx eax, al + to_lower eax + imul ebx, edx + add ebx, eax + loop strhashi_l1 + endif + ret + +;;;;;;;;;;;;;;;;;;; +; syscall functions +;;;;;;;;;;;;;;;;;;; + +_syscall: + int 0x80 + if c + neg eax + endif + ret + +_lsyscall: + int 0x80 + if c + not eax + not edx + add eax, 1 + adc edx, 0 + endif + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; built in variables +; STATE Is the interpreter executing code (0) or compiling a word (non-zero)? +; LATEST Points to the latest (most recently defined) word in the dictionary. +; DP Points to the next free byte of memory. When compiling, compiled words go here. +; S0 Stores the address of the top of the parameter stack. +; R0 The address of the top of the return stack. +; BASE The current base for printing and reading numbers. +; #IN The current input buffer descriptor. +; >IN The current input offset. +; SOURCEFD The current input source file descriptor. +; BLK The current block number. +; CHARBUF Single char buffer. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + defvar "state", 0, WORD_STATE, 0 + defvar "dp", 0, WORD_DP, dictionary_start + defvar "latest", 0, WORD_LATEST, 0 + defvar "s0", 0, WORD_SZ, 0 + defvar "r0", 0, WORD_RZ, 0 + defvar "base", 0, WORD_BASE, 10 + defvar2 "#IN", 0, WORD_INHASH, 0, 0 + defvar ">in", 0, WORD_TOIN, 0 + defvar "sourcefd", 0, WORD_SOURCEFD, 0 + defvar "blk", 0, WORD_BLK, 0 + defvar "charbuf", 0, WORD_CHARBUF, 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; built in constants +; VERSION The current version of this FORTH. +; WORDBUF The address of the buffer WORD uses. +; LINESIZE The line buffer size. +; F_IMMED The IMMEDIATE flag's actual value. +; F_HIDDEN The HIDDEN flag's actual value. +; F_LENMASK The length mask in the flags/len byte. +; H_NSIZE The flags/len field offset. +; H_NAME The name field offset. +; XT_BODY The xt body pointer. +; XT_LENGTH The xt length field offset. +; XT_COMPILE The xt compile field offset. +; XT_SIZE The xt size offset. +; SYS_* The numeric codes of various syscalls. +; O_* Various sycall flags/modes. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + defconst "version", 0, WORD_VERSION, VERSION_NUM + defconst "wordbuf", 0, WORD_WORDBUF, word_buf + defconst "linesize", 0, WORD_LINESIZE, MAX_LINE_SIZE + defconst "f_immed", 0, WORD__F_IMMED, F_IMMED + defconst "f_hidden", 0, WORD__F_HIDDEN, F_HIDDEN + defconst "f_lenmask", 0, WORD__F_LENMASK, F_LENMASK + defconst "h_nsize", 0, WORD__H_NSIZE, H_NSIZE + defconst "h_name", 0, WORD__H_NAME, H_NAME + defconst "xt_body", 0, WORD__XT_BODY, XT_BODY + defconst "xt_length", 0, WORD__XT_LENGTH, XT_LENGTH + defconst "xt_compile", 0, WORD__XT_COMPILE, XT_COMPILE + defconst "xt_size", 0, WORD__XT_SIZE, XT_SIZE + + defconst "sys_exit", 0, WORD_SYS_EXIT, SYS_exit + defconst "sys_open", 0, WORD_SYS_OPEN, SYS_open + defconst "sys_close", 0, WORD_SYS_CLOSE, SYS_close + defconst "sys_read", 0, WORD_SYS_READ, SYS_read + defconst "sys_write", 0, WORD_SYS_WRITE, SYS_write + defconst "sys_unlink", 0, WORD_SYS_UNLINK, SYS_unlink + defconst "sys_rename", 0, WORD_SYS_RENAME, SYS_rename + defconst "sys_ftruncate", 0, WORD_SYS_FTRUNCATE, SYS_ftruncate + defconst "sys_fsync", 0, WORD_SYS_FSYNC, SYS_fsync + defconst "sys_lseek", 0, WORD_SYS_LSEEK, SYS_lseek + defconst "sys_fstat", 0, WORD_SYS_FSTAT, SYS_fstat + defconst "sys_stat", 0, WORD_SYS_STAT, SYS_stat + + defconst "o_rdonly", 0, WORD_O_RDONLY, 0x0 + defconst "o_wronly", 0, WORD_O_WRONLY, 0x1 + defconst "o_rdwr", 0, WORD_O_RDWR, 0x2 + defconst "o_creat", 0, WORD_O_CREAT, 0x100 + defconst "o_excl", 0, WORD_O_EXCL, 0x200 + defconst "o_trunc", 0, WORD_O_TRUNC, 0x1000 + defconst "o_append", 0, WORD_O_APPEND, 0x2000 + defconst "o_nonblock", 0, WORD_O_NONBLOCK, 0x4000 + +;;;;;;;;;;;;;;;;;;;;;;;;;;; +; data stack ordering words +;;;;;;;;;;;;;;;;;;;;;;;;;;; + + defword "dsp@", 0, WORD_DSPFETCH, WORD_INLINE_COMMA + PUSHDSP ebx + GETDSP ebx + ret + defword_end + + defword "dsp!", 0, WORD_DSPSTORE, WORD_INLINE_COMMA + SETDSP ebx + POPDSP ebx + ret + defword_end + + defword "drop", 0, WORD_DROP, WORD_INLINE_COMMA + POPDSP ebx + ret + defword_end + + defword "swap", 0, WORD_SWAP, WORD_INLINE_COMMA + xchg ebx, [ebp] + ret + defword_end + + defword "dup", 0, WORD_DUP, WORD_INLINE_COMMA + PUSHDSP ebx + ret + defword_end + + defword "over", 0, WORD_OVER, WORD_INLINE_COMMA + PUSHDSP ebx + PICKDSP ebx, 4 + ret + defword_end + + defword "rot", 0, WORD_ROT, WORD_INLINE_COMMA + mov eax, ebx + PICKDSP ecx, 0 + PICKDSP ebx, 4 + PUTDSP eax, 0 + PUTDSP ecx, 4 + ret + defword_end + + defword "-rot", 0, WORD_NROT, WORD_INLINE_COMMA + mov eax, ebx + PICKDSP ebx, 0 + PICKDSP ecx, 4 + PUTDSP ecx, 0 + PUTDSP eax, 4 + ret + defword_end + + defword "2drop", 0, WORD_DROP2, WORD_INLINE_COMMA + PICKDSP ebx, 4 + ADDDSP 8 + ret + defword_end + + defword "2dup", 0, WORD_DUP2, WORD_INLINE_COMMA + PICKDSP eax, 0 + ADDDSP -8 + PUTDSP eax, 0 + PUTDSP ebx, 4 + ret + defword_end + + defword "2swap", 0, WORD_SWAP2, WORD_INLINE_COMMA + mov eax, ebx + PICKDSP ecx, 0 + PICKDSP ebx, 4 + PICKDSP edx, 8 + PUTDSP edx, 0 + PUTDSP eax, 4 + PUTDSP ecx, 8 + ret + defword_end + + defword "2rot", 0, WORD_ROT2, WORD_INLINE_COMMA + mov eax, ebx + PICKDSP ecx, 16 + PICKDSP ebx, 12 + PICKDSP edx, 8 + PICKDSP edi, 4 + PICKDSP esi, 0 + PUTDSP edx, 16 + PUTDSP edi, 12 + PUTDSP esi, 8 + PUTDSP eax, 4 + PUTDSP ecx, 0 + ret + defword_end + + defword "?dup", 0, WORD_QDUP, WORD_INLINE_COMMA + test ebx, ebx + if nz + PUSHDSP ebx + endif + ret + defword_end + + defword "!?dup", 0, WORD_NQDUP, WORD_INLINE_COMMA + test ebx, ebx + if z + PUSHDSP ebx + endif + ret + defword_end + + defword "nip", 0, WORD_NIP, WORD_INLINE_COMMA + ADDDSP 4 + ret + defword_end + + defword "tuck", 0, WORD_TUCK, WORD_INLINE_COMMA + PICKDSP eax, 0 + PUTDSP ebx, 0 + PUSHDSP eax + ret + defword_end + + defword "pick", 0, WORD_PICK, WORD_INLINE_COMMA + mov ebx, [ebp + (ebx * 4)] + ret + defword_end + + defword "2tuck", 0, WORD_TUCK2, WORD_INLINE_COMMA + PICKDSP eax, 0 + PICKDSP ecx, 4 + PICKDSP edx, 8 + ADDDSP -8 + PUTDSP eax, 0 + PUTDSP ecx, 4 + PUTDSP edx, 8 + PUTDSP ebx, 12 + PUTDSP eax, 16 + ret + defword_end + + defword "2nip", 0, WORD_NIP2, WORD_INLINE_COMMA + PICKDSP eax, 0 + ADDDSP 8 + PUTDSP eax, 0 + ret + defword_end + + defword "2over", 0, WORD_OVER2, WORD_INLINE_COMMA + ADDDSP -8 + PUTDSP ebx, 4 + PICKDSP ebx, 16 + PUTDSP ebx, 0 + PICKDSP ebx, 12 + ret + defword_end + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; return stack ordering words +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + defword ">r", 0, WORD_TOR, WORD_INLINE_COMMA + TORSP + ret + defword_end + + defword "r>", 0, WORD_FROMR, WORD_INLINE_COMMA + FROMRSP + ret + defword_end + + defword "2>r", 0, WORD_TOR2, WORD_INLINE_COMMA + ADDRSP -8 + PICKDSP ecx, 0 + PUTRSP ebx, 0 + PUTRSP ecx, 4 + PICKDSP ebx, 4 + ADDDSP 8 + ret + defword_end + + defword "2r>", 0, WORD_FROMR2, WORD_INLINE_COMMA + ADDDSP -8 + PUTDSP ebx, 4 + PICKRSP ebx, 0 + PICKRSP ecx, 4 + PUTDSP ecx, 0 + ADDRSP 8 + ret + defword_end + + defword "rsp@", 0, WORD_RSPFETCH, WORD_INLINE_COMMA + PUSHDSP ebx + GETRSP ebx + ret + defword_end + + defword "r@", 0, WORD_RFETCH, WORD_INLINE_COMMA + PUSHDSP ebx + PICKRSP ebx, 0 + ret + defword_end + + defword "r!", 0, WORD_RSTORE, WORD_INLINE_COMMA + PUTRSP ebx, 0 + POPDSP ebx + ret + defword_end + + defword "2r@", 0, WORD_RFETCH2, WORD_INLINE_COMMA + ADDDSP -8 + PUTDSP ebx, 4 + PICKRSP ebx, 4 + PICKRSP ecx, 0 + PUTDSP ecx, 0 + ret + defword_end + + defword "rsp!", 0, WORD_RSPSTORE, WORD_INLINE_COMMA + SETRSP ebx + POPDSP ebx + ret + defword_end + + defword "rdrop", 0, WORD_RDROP, WORD_INLINE_COMMA + ADDRSP 4 + ret + defword_end + + defword "2rdrop", 0, WORD_RDROP2, WORD_INLINE_COMMA + ADDRSP 8 + ret + defword_end + + defword "n>r", 0, WORD_NTOR, WORD_CALL_COMMA + PUSHDSP ebx + PICKRSP eax, 0 + mov ecx, ebx + inc ecx + neg ebx + lea esp, [esp + (ebx * 4)] + mov esi, ebp + mov edi, esp + rep movsd + mov ebp, esi + POPDSP ebx + jmp eax + defword_end + + defword "nr>", 0, WORD_NFROMR, WORD_CALL_COMMA + PUSHDSP ebx + POPRSP eax + PICKRSP ebx, 0 + inc ebx + mov ecx, ebx + neg ebx + lea ebp, [ebp + (ebx * 4)] + mov esi, esp + mov edi, ebp + rep movsd + mov esp, esi + POPDSP ebx + jmp eax + defword_end + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; memory fetch and store words +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + defword "!", 0, WORD_STORE, WORD_INLINE_COMMA + PICKDSP eax, 0 + mov [ebx], eax + PICKDSP ebx, 4 + ADDDSP 8 + ret + defword_end + + defword "@", 0, WORD_FETCH, WORD_INLINE_COMMA + mov ebx, [ebx] + ret + defword_end + + defword "+!", 0, WORD_ADDSTORE, WORD_INLINE_COMMA + PICKDSP eax, 0 + add [ebx], eax + PICKDSP ebx, 4 + ADDDSP 8 + ret + defword_end + + defword "-!", 0, WORD_SUBSTORE, WORD_INLINE_COMMA + PICKDSP eax, 0 + sub [ebx], eax + PICKDSP ebx, 4 + ADDDSP 8 + ret + defword_end + + defword "c!", 0, WORD_STOREBYTE, WORD_INLINE_COMMA + PICKDSP eax, 0 + mov [ebx], al + PICKDSP ebx, 4 + ADDDSP 8 + ret + defword_end + + defword "c+!", 0, WORD_ADDBYTE, WORD_INLINE_COMMA + PICKDSP eax, 0 + add [ebx], al + PICKDSP ebx, 4 + ADDDSP 8 + ret + defword_end + + defword "c@", 0, WORD_FETCHBYTE, WORD_INLINE_COMMA + mov eax, ebx + xor ebx, ebx + mov bl, [eax] + ret + defword_end + + defword "w!", 0, WORD_STORESHORT, WORD_INLINE_COMMA + PICKDSP eax, 0 + mov [ebx], ax + PICKDSP ebx, 4 + ADDDSP 8 + ret + defword_end + + defword "w@", 0, WORD_FETCHSHORT, WORD_INLINE_COMMA + mov eax, ebx + xor ebx, ebx + mov bx, [eax] + ret + defword_end + + defword "2!", 0, WORD_STORE2, WORD_INLINE_COMMA + PICKDSP ecx, 4 + PICKDSP edx, 0 + mov [ebx + 4], ecx + mov [ebx], edx + PICKDSP ebx, 8 + ADDDSP 12 + ret + defword_end + + defword "2@", 0, WORD_FETCH2, WORD_INLINE_COMMA + ADDDSP -4 + mov ecx, [ebx +4] + mov ebx, [ebx] + PUTDSP ecx, 0 + ret + defword_end + + defword "blank", 0, WORD_BLANK, WORD_CALL_COMMA + mov ecx, ebx + PICKDSP ebx, 4 + PICKDSP edi, 0 + ADDDSP 8 + mov eax, 0x20 + rep stosb + ret + defword_end + + defword "erase", 0, WORD_ERASE, WORD_CALL_COMMA + mov ecx, ebx + PICKDSP ebx, 4 + PICKDSP edi, 0 + ADDDSP 8 + xor eax, eax + rep stosb + ret + defword_end + + defword "fill", 0, WORD_FILL, WORD_CALL_COMMA + mov eax, ebx + PICKDSP ebx, 8 + PICKDSP edi, 4 + PICKDSP ecx, 0 + ADDDSP 12 + rep stosb + ret + defword_end + + defword "cmove>", 0, WORD_CMOVEB, WORD_CALL_COMMA + mov ecx, ebx + PICKDSP ebx, 8 + PICKDSP esi, 4 + PICKDSP edi, 0 + ADDDSP 12 + lea esi, [esi + ecx - 1] + lea edi, [edi + ecx - 1] + std + rep movsb + cld + ret + defword_end + + defword "cmove", 0, WORD_CMOVE, WORD_CALL_COMMA + mov ecx, ebx + PICKDSP ebx, 8 + PICKDSP esi, 4 + PICKDSP edi, 0 + ADDDSP 12 + rep movsb + ret + defword_end + + defword "move", 0, WORD_MOVE, WORD_CALL_COMMA + mov ecx, ebx + PICKDSP ebx, 8 + PICKDSP esi, 4 + PICKDSP edi, 0 + ADDDSP 12 + cmp esi, edi + if a + rep movsb + else + lea esi, [esi + ecx -1] + lea edi, [edi + ecx -1] + std + rep movsb + cld + endif + ret + defword_end + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; single precision alu words +;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + defword "+", 0, WORD_ADD, WORD_INLINE_COMMA + add ebx, [ebp] + ADDDSP 4 + ret + defword_end + + defword "-", 0, WORD_SUB, WORD_INLINE_COMMA + mov eax, ebx + POPDSP ebx + sub ebx, eax + ret + defword_end + + defword "*", 0, WORD_MULL, WORD_INLINE_COMMA + imul ebx, [ebp] + ADDDSP 4 + ret + defword_end + + defword "/", 0, WORD_DIV, WORD_INLINE_COMMA + POPDSP eax + cdq + idiv ebx + mov ebx, eax + ret + defword_end + + defword "mod", 0, WORD_MOD, WORD_INLINE_COMMA + POPDSP eax + cdq + idiv ebx + mov ebx, edx + ret + defword_end + + defword "1+", 0, WORD_INCR, WORD_INLINE_COMMA + add ebx, byte 1 + ret + defword_end + + defword "1-", 0, WORD_DECR, WORD_INLINE_COMMA + sub ebx, byte 1 + ret + defword_end + + defword "4+", 0, WORD_INCR4, WORD_INLINE_COMMA + add ebx, byte 4 + ret + defword_end + + defword "4-", 0, WORD_DECR4, WORD_INLINE_COMMA + sub ebx, byte 4 + ret + defword_end + + defword "2+", 0, WORD_INCR2, WORD_INLINE_COMMA + add ebx, byte 2 + ret + defword_end + + defword "2-", 0, WORD_DECR2, WORD_INLINE_COMMA + sub ebx, byte 2 + ret + defword_end + + defword "2*", 0, WORD_TWOMUL, WORD_INLINE_COMMA + shl ebx, byte 1 + ret + defword_end + + defword "2/", 0, WORD_TWODIV, WORD_INLINE_COMMA + sar ebx, byte 1 + ret + defword_end + + defword "abs", 0, WORD_ABS, WORD_INLINE_COMMA + mov eax, ebx + sar eax, byte 31 + add ebx, eax + xor ebx, eax + ret + defword_end + + defword "min", 0, WORD_MIN, WORD_INLINE_COMMA + POPDSP eax + cmp ebx, eax + if g + mov ebx, eax + endif + ret + defword_end + + defword "max", 0, WORD_MAX, WORD_INLINE_COMMA + POPDSP eax + cmp ebx, eax + if l + mov ebx, eax + endif + ret + defword_end + + defword "lshift", 0, WORD_LSHIFT, WORD_INLINE_COMMA + mov ecx, ebx + POPDSP ebx + shl ebx, cl + ret + defword_end + + defword "rshift", 0, WORD_RSHIFT, WORD_INLINE_COMMA + mov ecx, ebx + POPDSP ebx + shr ebx, cl + ret + defword_end + + defword "and", 0, WORD_AND, WORD_INLINE_COMMA + and ebx, [ebp] + ADDDSP 4 + ret + defword_end + + defword "or", 0, WORD_OR, WORD_INLINE_COMMA + or ebx, [ebp] + ADDDSP 4 + ret + defword_end + + defword "xor", 0, WORD_XOR, WORD_INLINE_COMMA + xor ebx, [ebp] + ADDDSP 4 + ret + defword_end + + defword "negate", 0, WORD_NEGATE, WORD_INLINE_COMMA + neg ebx + ret + defword_end + + defword "invert", 0, WORD_INVERT, WORD_INLINE_COMMA + not ebx + ret + defword_end + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; single precision comparision words +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + defword "=", 0, WORD_EQ, WORD_INLINE_COMMA + cmp [ebp], ebx + sete bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "<>", 0, WORD_NE, WORD_INLINE_COMMA + cmp [ebp], ebx + setne bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "<", 0, WORD_LT, WORD_INLINE_COMMA + cmp [ebp], ebx + setl bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword ">", 0, WORD_GT, WORD_INLINE_COMMA + cmp [ebp], ebx + setg bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "u<", 0, WORD_ULT, WORD_INLINE_COMMA + cmp [ebp], ebx + setb bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "u>", 0, WORD_UGT, WORD_INLINE_COMMA + cmp [ebp], ebx + seta bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "u<=", 0, WORD_ULTEQ, WORD_INLINE_COMMA + cmp [ebp], ebx + setbe bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "u>=", 0, WORD_UGTEQ, WORD_INLINE_COMMA + cmp [ebp], ebx + setae bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "<=", 0, WORD_LTEQ, WORD_INLINE_COMMA + cmp [ebp], ebx + setle bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword ">=", 0, WORD_GTEQ, WORD_INLINE_COMMA + cmp [ebp], ebx + setge bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "0=", 0, WORD_ZEQ, WORD_INLINE_COMMA + test ebx, ebx + setz bl + movzx ebx, bl + neg ebx + ret + defword_end + + defword "0<>", 0, WORD_ZNE, WORD_INLINE_COMMA + test ebx, ebx + setnz bl + movzx ebx, bl + neg ebx + ret + defword_end + + defword "0<", 0, WORD_ZLT, WORD_INLINE_COMMA + test ebx, ebx + setl bl + movzx ebx, bl + neg ebx + ret + defword_end + + defword "0>", 0, WORD_ZGT, WORD_INLINE_COMMA + test ebx, ebx + setg bl + movzx ebx, bl + neg ebx + ret + defword_end + + defword "0<=", 0, WORD_ZLTEQ, WORD_INLINE_COMMA + test ebx, ebx + setle bl + movzx ebx, bl + neg ebx + ret + defword_end + + defword "0>=", 0, WORD_ZGTEQ, WORD_INLINE_COMMA + test ebx, ebx + setge bl + movzx ebx, bl + neg ebx + ret + defword_end + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; double precision ALU words +;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + defword "s>d", 0, WORD_STOD, WORD_INLINE_COMMA + mov eax, ebx + cdq + PUSHDSP eax + mov ebx, edx + ret + defword_end + + defword "d>s", 0, WORD_DTOS, WORD_INLINE_COMMA + POPDSP ebx + ret + defword_end + + defword "d+", 0, WORD_DPLUS, WORD_INLINE_COMMA + PICKDSP ecx, 8 + PICKDSP edx, 4 + PICKDSP eax, 0 + add eax, ecx + adc ebx, edx + PUTDSP eax, 8 + ADDDSP 8 + ret + defword_end + + defword "d-", 0, WORD_DMINUS, WORD_INLINE_COMMA + PICKDSP ecx, 8 + PICKDSP edx, 4 + PICKDSP eax, 0 + sub ecx, eax + sbb edx, ebx + PUTDSP ecx, 8 + mov ebx, edx + ADDDSP 8 + ret + defword_end + + defword "d2*", 0, WORD_D2STAR, WORD_INLINE_COMMA + PICKDSP eax, 0 + shl eax, 1 + rcl ebx, 1 + PUTDSP eax, 0 + ret + defword_end + + defword "d2/", 0, WORD_D2SLASH, WORD_INLINE_COMMA + PICKDSP eax, 0 + sar ebx, 1 + rcr eax, 1 + PUTDSP eax, 0 + ret + defword_end + + defword "*/", 0, WORD_MULDIV, WORD_INLINE_COMMA + PICKDSP edx, 4 + PICKDSP eax, 0 + imul edx + idiv ebx + mov ebx, eax + ADDDSP 8 + ret + defword_end + + defword "*/mod", 0, WORD_STARSMOD, WORD_INLINE_COMMA + PICKDSP edx, 4 + PICKDSP eax, 0 + imul edx + idiv ebx + PUTDSP edx, 4 + ADDDSP 4 + mov ebx, eax + ret + defword_end + + defword "/mod", 0, WORD_DIVMOD, WORD_INLINE_COMMA + PICKDSP eax, 0 + cdq + idiv ebx + PUTDSP edx, 0 + mov ebx, eax + ret + defword_end + + defword "dnegate", 0, WORD_DNEGATE, WORD_INLINE_COMMA + PICKDSP eax, 0 + not eax + not ebx + add eax, 1 + adc ebx, 0 + PUTDSP eax, 0 + ret + defword_end + + defword "dabs", 0, WORD_DABS, WORD_INLINE_COMMA + test ebx, ebx + if l + PICKDSP eax, 0 + not eax + not ebx + add eax, 1 + adc ebx, 0 + PUTDSP eax, 0 + endif + ret + defword_end + + defword "dmax", 0, WORD_DMAX, WORD_INLINE_COMMA + PICKDSP ecx, 8 + PICKDSP edx, 4 + PICKDSP eax, 0 + ADDDSP 8 + mov esi, ecx + mov edi, edx + sub esi, eax + sbb edi, ebx + if l + PUTDSP eax, 0 + else + mov ebx, edx + endif + ret + defword_end + + defword "dmin", 0, WORD_DMIN, WORD_INLINE_COMMA + PICKDSP ecx, 8 + PICKDSP edx, 4 + PICKDSP eax, 0 + ADDDSP 8 + mov esi, ecx + mov edi, edx + sub esi, eax + sbb edi, ebx + if ge + PUTDSP eax, 0 + else + mov ebx, edx + endif + ret + defword_end + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; double precision comparision words +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + defword "d0=", 0, WORD_DZEQ, WORD_INLINE_COMMA + or ebx, [ebp] + setz bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "d0<>", 0, WORD_DZNEQ, WORD_INLINE_COMMA + or ebx, [ebp] + setnz bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "d0<", 0, WORD_DZLT, WORD_INLINE_COMMA + test ebx, ebx + setl bl + ADDDSP 4 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "d=", 0, WORD_DEQ, WORD_INLINE_COMMA + PICKDSP ecx, 8 + PICKDSP eax, 4 + sub ecx, [ebp] + sbb eax, ebx + setz bl + ADDDSP 12 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "d<>", 0, WORD_DNEQ, WORD_INLINE_COMMA + PICKDSP ecx, 8 + PICKDSP eax, 4 + sub ecx, [ebp] + sbb eax, ebx + setnz bl + ADDDSP 12 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "d<", 0, WORD_DLT, WORD_INLINE_COMMA + PICKDSP ecx, 8 + PICKDSP eax, 4 + sub ecx, [ebp] + sbb eax, ebx + setl bl + ADDDSP 12 + movzx ebx, bl + neg ebx + ret + defword_end + + defword "du<", 0, WORD_DULT, WORD_INLINE_COMMA + PICKDSP ecx, 8 + PICKDSP eax, 4 + sub ecx, [ebp] + sbb eax, ebx + setb bl + ADDDSP 12 + movzx ebx, bl + neg ebx + ret + defword_end + +;;;;;;;;;;;;;;;;;;;;;;; +; mixed precision words +;;;;;;;;;;;;;;;;;;;;;;; + + defword "m+", 0, WORD_MPLUS, WORD_INLINE_COMMA + PICKDSP eax, 4 + PICKDSP edx, 0 + add eax, ebx + adc edx, 0 + PUTDSP eax, 4 + mov ebx, edx + ADDDSP 4 + ret + defword_end + + defword "m-", 0, WORD_MMINUS, WORD_INLINE_COMMA + PICKDSP eax, 4 + PICKDSP edx, 0 + sub eax, ebx + sbb edx, 0 + PUTDSP eax, 4 + mov ebx, edx + ADDDSP 4 + ret + defword_end + + defword "m*", 0, WORD_MULSTAR, WORD_INLINE_COMMA + PICKDSP eax, 0 + imul ebx + PUTDSP eax, 0 + mov ebx, edx + ret + defword_end + + defword "m/", 0, WORD_MSLASH, WORD_INLINE_COMMA + PICKDSP eax, 4 + PICKDSP edx, 0 + idiv ebx + mov ebx, eax + ADDDSP 8 + ret + defword_end + + defword "um*", 0, WORD_UMULSTAR, WORD_INLINE_COMMA + PICKDSP eax, 0 + mul ebx + PUTDSP eax, 0 + mov ebx, edx + ret + defword_end + + defword "um/mod", 0, WORD_UMDIVMOD, WORD_INLINE_COMMA + PICKDSP eax, 4 + PICKDSP edx, 0 + div ebx + PUTDSP edx, 4 + mov ebx, eax + ADDDSP 4 + ret + defword_end + + defword "fm/mod", 0, WORD_FMDIVMOD, WORD_INLINE_COMMA + PICKDSP edx, 0 + PICKDSP eax, 4 + mov ecx, ebx + ADDDSP 4 + xor ecx, edx + idiv ebx + test ecx, ecx + if s + test edx, edx + if nz + dec eax + add edx, ebx + endif + endif + PUTDSP edx, 0 + mov ebx, eax + ret + defword_end + + defword "sm/rem", 0, WORD_SMDIVREM, WORD_INLINE_COMMA + PICKDSP eax, 4 + PICKDSP edx, 0 + idiv ebx + PUTDSP edx, 4 + mov ebx, eax + ADDDSP 4 + ret + defword_end + + defword "u/mod", 0, WORD_UDIVMOD, WORD_INLINE_COMMA + xor edx, edx + PICKDSP eax, 0 + div ebx + PUTDSP edx, 0 + mov ebx, eax + ret + defword_end + + defword "dm*", 0, WORD_DMULSTAR, WORD_CALL_COMMA + call WORD_TUCK + call WORD_MULL + TORSP + call WORD_UMULSTAR + FROMRSP + call WORD_ADD + ret + defword_end + +;;;;;;;;;;;;;;;;;;;; +; control flow words +;;;;;;;;;;;;;;;;;;;; + + defword "branch", 0, WORD_BRANCH, WORD_INLINE_COMMA +i_jmp: + jmp strict near i_ret + ret + defword_end + + defword "0branch", 0, WORD_ZBRANCH, WORD_INLINE_COMMA + mov eax, ebx + POPDSP ebx + test eax, eax + jz strict near i_jmp + ret + defword_end + + defword "exit", 0, WORD_EXIT, WORD_EXIT_COMMA +i_ret: + ret + defword_end + + defword "exit,", 0, WORD_EXIT_COMMA, WORD_CALL_COMMA + mov edi, [var_WORD_DP] + sub edi, 5 + cmp edi, [lastcall] ; are we just after a call instruction ? + if z + mov al, [i_jmp] + mov [edi], al ; change it to a jmp + endif + mov edi, [var_WORD_DP] + mov al, [i_ret] + stosb + mov [var_WORD_DP], edi + POPDSP ebx + ret + defword_end + + defword "execute", 0, WORD_EXECUTE, WORD_CALL_COMMA + mov eax, ebx ; Get xt into eax + POPDSP ebx ; After xt runs its ret will continue executing the current word. + jmp eax ; and jump to it. + defword_end + +;;;;;;;;;;;;;;;;;;;;;;;;;; +; terminal input words +;;;;;;;;;;;;;;;;;;;;;;;;;; + + defword "read-char", 0, WORD_READCHAR, WORD_CALL_COMMA + mov ecx, var_WORD_CHARBUF ; 2nd param: buffer + mov edx, 1 ; 3rd param: max length + push edx + push ecx + push ebx + mov eax, SYS_read ; syscall: read + call _syscall + add esp, 12 + xor ebx, ebx + test eax, eax + if be + mov ebx, -1 + endif + ret + defword_end + + defword "read-line", 0, WORD_READLINE, WORD_CALL_COMMA + call WORD_NROT + call WORD_OVER + call WORD_ADD + call WORD_OVER ; ( fd start end cur ) +readline_l1: + PICKDSP eax, 0 + cmp ebx, eax + jz readline_l4 + PUSHDSP ebx + PICKDSP ebx, 12 + call WORD_READCHAR + test ebx, ebx + jz readline_l2 + call WORD_DROP + call WORD_DROP2 + call WORD_DROP2 + LOADTOS 0 + LOADTOS 0 + LOADTOS -1 + jmp readline_l5 +readline_l2: + mov ebx, [var_WORD_CHARBUF] + cmp ebx, 10 ; LF + jz readline_l3 + call WORD_OVER + call WORD_STOREBYTE + call WORD_INCR + jmp readline_l1 +readline_l3: + call WORD_DROP +readline_l4: + call WORD_NIP + call WORD_SWAP + call WORD_SUB + call WORD_NIP + LOADTOS -1 + LOADTOS 0 +readline_l5: + ret + defword_end + + defword "key", 0, WORD_KEY, WORD_CALL_COMMA + PUSHDSP ebx + xor ebx, ebx ; stdin + call WORD_READCHAR + mov ebx, [var_WORD_CHARBUF] + ret + defword_end + + defword "accept", 0, WORD_ACCEPT, WORD_CALL_COMMA + call WORD_OVER + call WORD_ADD + call WORD_OVER ; ( start end cur ) +accept_l1: + call WORD_KEY + cmp ebx, 127 ; BS + jz accept_l2 + cmp ebx, 10 ; LF + jz accept_l3 + call WORD_OVER ; ( start end cur key cur ) + call WORD_STOREBYTE + call WORD_INCR ; ( start end cur' ) + PICKDSP eax, 0 + cmp ebx, eax + jz accept_l4 + jmp accept_l1 +accept_l2: + PICKDSP eax, 4 ; ( start end cur' ) + cmp ebx, eax + jz accept_l1 + call WORD_DECR + jmp accept_l1 +accept_l3: + call WORD_DROP ; ( start end cur' ) +accept_l4: + call WORD_NIP + call WORD_SWAP + call WORD_SUB + ret + defword_end + + defword "tabs>spaces", 0, WORD_TABSTOSPACES, WORD_CALL_COMMA + mov ecx, ebx + POPDSP esi + test ecx, ecx + if nz + repeat + lodsb + cmp al, 9 ;TAB + if z + mov byte [esi - 1], ' ' + endif + dec ecx + until z + endif + POPDSP ebx + ret + defword_end + +;;;;;;;;;;;;;;;;;;;;;;; +; terminal output words +;;;;;;;;;;;;;;;;;;;;;;; + + defword "type-fd", 0, WORD_TYPE_FD, WORD_CALL_COMMA + PICKDSP edx, 0 ; 3rd param: length of string + PICKDSP ecx, 4 ; 2nd param: address of string + ADDDSP 8 ; 1st param: FD in ebx + mov eax, SYS_write ; write syscall + push edx + push ecx + push ebx + call _syscall + add esp, 12 + POPDSP ebx + ret + defword_end + + defword "type", 0, WORD_TYPE, WORD_CALL_COMMA + LOADTOS 1 ; stdout + call WORD_TYPE_FD + ret + defword_end + + defword "emit", 0, WORD_EMIT, WORD_CALL_COMMA + mov [emit_scratch], bl ; write needs the address of the byte to write + mov ebx, emit_scratch + LOADTOS 1 + call WORD_TYPE + ret + defword_end + +;;;;;;;;;;;;;;;;;;; +; system call words +;;;;;;;;;;;;;;;;;;; + + defword "syscall", 0, WORD_SYSCALL, WORD_CALL_COMMA + pop eax + mov [syscallret], eax ; save return address + mov eax, ebx ; System call number (see ) + call _syscall + mov ebx, eax ; Result (negative for -errno) + jmp [syscallret] ; return to caller + defword_end + + defword "lsyscall", 0, WORD_LSYSCALL, WORD_CALL_COMMA + pop eax + mov [syscallret], eax ; save return address + mov eax, ebx ; System call number (see ) + call _lsyscall + PUSHDSP eax + mov ebx, edx ; Result (negative for -errno) + jmp [syscallret] ; return to caller + defword_end + +;;;;;;;;;;;;;; +; string words +;;;;;;;;;;;;;; + + defword "count", 0, WORD_COUNT, WORD_CALL_COMMA + xor eax, eax + mov al, [ebx] + inc ebx + LOADTOS eax + ret + defword_end + + defword "-trailing", 0, WORD_TRAILING, WORD_CALL_COMMA + test ebx, ebx + if nz + PICKDSP esi, 0 + mov ecx, ebx + add esi, ebx + dec esi + std + trailing_l1: + lodsb + cmp al, ' ' + if be + loop trailing_l1 + endif + mov ebx, ecx + cld + endif + ret + defword_end + + defword "/string", 0, WORD_SSTRING, WORD_CALL_COMMA + mov eax, ebx + POPDSP ebx + PICKDSP ecx, 0 + sub ebx, eax + add ecx, eax + PUTDSP ecx, 0 + ret + defword_end + + defword "compare", 0, WORD_COMPARE, WORD_CALL_COMMA + PICKDSP esi, 8 + PICKDSP edx, 4 + PICKDSP edi, 0 + ADDDSP 12 + mov ecx, ebx + cmp edx, ebx + if be + mov ecx, edx + endif + test ecx, ecx ; ecx lowest length + jnz compare_l2 + cmp edx, ebx + jz compare_l3 ; both are 0 length + jmp compare_l4 ; otherwise the longest wins +compare_l2: + cmpsb + jnz compare_l4 ; chars not same + loop compare_l2 + cmp edx, ebx ; all chars same + jnz compare_l4 ; strings not same size +compare_l3: + xor ebx, ebx ; same + jmp compare_l7 +compare_l4: + ja compare_l6 +compare_l5: + mov ebx, -1 + jmp compare_l7 +compare_l6: + mov ebx, 1 +compare_l7: + ret + defword_end + + defword "icompare", 0, WORD_COMPAREI, WORD_CALL_COMMA + PICKDSP esi, 8 + PICKDSP edx, 4 + PICKDSP edi, 0 + ADDDSP 12 + mov ecx, ebx + cmp edx, ebx + if be + mov ecx, edx + endif + test ecx, ecx ; ecx lowest length + jnz comparei_l2 + cmp edx, ebx + jz comparei_l3 ; both are 0 length + jmp comparei_l4 ; otherwise the longest wins +comparei_l2: + mov al, [esi] + mov ah, [edi] + to_lower al + to_lower ah + cmp ah, al + jnz comparei_l4 ; chars not same + inc edi + inc esi + loop comparei_l2 + cmp edx, ebx ; all chars same + jnz comparei_l4 ; strings not same size +comparei_l3: + xor ebx, ebx ; same + jmp comparei_l7 +comparei_l4: + ja comparei_l6 +comparei_l5: + mov ebx, -1 + jmp comparei_l7 +comparei_l6: + mov ebx, 1 +comparei_l7: + ret + defword_end + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; dictionary searching words +;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + defword "find", 0, WORD_FIND, WORD_CALL_COMMA + call WORD_DUP + call WORD_COUNT + call WORD_FIND_DICT + test ebx, ebx + if nz + mov dl, [ebx + H_NSIZE] + call WORD_TCFA + LOADTOS 1 + and edx, F_IMMED + if z + neg ebx + endif + call WORD_ROT + call WORD_DROP + endif + ret + defword_end + + defword "(find)", 0, WORD_FIND_DICT, WORD_CALL_COMMA + mov ecx, ebx ; ecx = length + POPDSP edi ; edi = address + PUSHRSP ecx + mov esi, edi + call strhashi + and ebx, NUM_HASH_CHAINS-1 + mov esi, hash_buckets + mov edx, [esi + (ebx * 4)] + POPRSP ecx ; edx can now scan back through this hash chain +findd_l1: + test edx, edx ; NULL pointer? (end of the linked list) + je findd_l4 + xor eax, eax + mov al, [edx + H_NSIZE] ; al = flags+length field + and al, (F_HIDDEN|F_LENMASK) ; al = name length + cmp al, cl ; Length is the same? + jne findd_l2 + PUSHRSP ecx ; Save the length + PUSHRSP edi ; Save the address (repe cmpsb will move this pointer) + lea esi, [edx + H_NAME] ; Dictionary string we are checking against. + call strcmpi + POPRSP edi + POPRSP ecx + jne findd_l2 ; Not the same. + mov ebx, edx + ret +findd_l2: + mov edx, [edx + H_HLINK] ; Move back through the link field to the previous word + jmp findd_l1 ; .. and loop. +findd_l4: + xor ebx, ebx ; Return zero to indicate not found. + ret + defword_end + + defword ">cfa", 0, WORD_TCFA, WORD_CALL_COMMA + add ebx, H_NSIZE + mov al, [ebx] ; Load flags+len into al. + inc ebx ; skip flags+len byte. + and eax, F_LENMASK ; Just the length, not the flags. + add ebx, eax ; skip the name + add ebx, XT_SIZE ; skip to the xt + ret + defword_end + + defword "(bucket)", 0, WORD_BUCKET, WORD_CALL_COMMA + mov ecx, ebx ; ecx = length + POPDSP ebx ; ebx = address of name + PUSHRSP esi + mov esi, ebx + call strhashi + and ebx, NUM_HASH_CHAINS-1 + mov esi, hash_buckets + lea ebx, [esi + (ebx * 4)] + POPRSP esi + ret + defword_end + + defword "unused", 0, WORD_UNUSED, WORD_CALL_COMMA + LOADTOS forth_end + LOADTOS [var_WORD_DP] + call WORD_SUB + ret + defword_end + +;;;;;;;;;;;;;;;;;;;;;;;;;;; +; dictionary building words +;;;;;;;;;;;;;;;;;;;;;;;;;;; + + defword "align", 0, WORD_ALIGNDP, WORD_CALL_COMMA + mov eax, [var_WORD_DP] + ALIGNREG eax + mov [var_WORD_DP], eax + ret + defword_end + + defword "header,", 0, WORD_HEADER_COMMA, WORD_CALL_COMMA + mov ecx, ebx ; ecx = length + POPDSP ebx ; ebx = address of name + call WORD_ALIGNDP ; align header + mov edi, [var_WORD_DP] ; edi is the address of the header + mov eax, [var_WORD_LATEST] ; Get link pointer + mov [edi + H_LLINK], eax ; and store it in the header. + mov [var_WORD_LATEST], edi + PUSHRSP ebx ; hash chain + PUSHRSP ecx + mov esi, ebx + call strhashi + and ebx, NUM_HASH_CHAINS-1 + mov esi, hash_buckets + mov eax, [esi + (ebx * 4)] + mov [esi + (ebx * 4)], edi + mov [edi + H_HLINK], eax ; and store it in the header. + POPRSP ecx + POPRSP esi + mov [edi + H_NSIZE], cl ; Store the length/flags byte. + add edi, H_NAME + call strcpyi + mov ecx, XT_SIZE + xor eax, eax + rep stosb ; clear the gap till the xt + mov [var_WORD_DP], edi + mov long [edi + XT_COMPILE], WORD_CALL_COMMA ;compile action + POPDSP ebx + ret + defword_end + + defword "lit,", 0, WORD_LIT_COMMA, WORD_CALL_COMMA + mov esi, litc_l1 + mov edi, [var_WORD_DP] + mov ecx, litc_l2 - litc_l1 - 4 + rep movsb + mov [var_WORD_DP], edi + ret + defword_end +litc_l1: + LOADTOS 0xBAADF00D +litc_l2: + + defword "slits", 0, WORD_SLITS, WORD_CALL_COMMA + PUSHDSP ebx + POPRSP esi + xor eax, eax + lodsb ; get the length of the string + PUSHDSP esi ; push the address of the start of the string + mov ebx, eax ; push length on the stack + add esi, eax ; skip past the string + jmp esi + defword_end + + defword "clits", 0, WORD_CLITS, WORD_CALL_COMMA + FROMRSP + xor eax, eax + mov al, [ebx] + lea eax, [ebx + eax + 1] + jmp eax + defword_end + + defword ",", 0, WORD_COMMA, WORD_CALL_COMMA + mov edi, [var_WORD_DP] ; DP + mov eax, ebx + stosd ; Store it. + mov [var_WORD_DP], edi ; Update DP (incremented) + POPDSP ebx + ret + defword_end + + defword "c,", 0, WORD_CHAR_COMMA, WORD_CALL_COMMA + mov eax, ebx + mov edi, [var_WORD_DP] ; DP + stosb ; Store it. + mov [var_WORD_DP], edi ; Update DP (incremented) + POPDSP ebx + ret + defword_end + + defword ":", 0, WORD_COLON, WORD_CALL_COMMA + call WORD_PARSENAME + call WORD_HEADER_COMMA ; Create the dictionary entry / header + mov eax, [var_WORD_DP] + mov [eax + XT_BODY], eax + call WORD_LATEST + call WORD_FETCH + call WORD_HIDDEN ; Make the word hidden + call WORD_RBRAC ; Go into compile mode. + ret + defword_end + + defword "create", 0, WORD_CREATE, WORD_CALL_COMMA + call WORD_PARSENAME + call WORD_HEADER_COMMA + mov esi, create_l1 + mov edi, [var_WORD_DP] + PUSHRSP edi + mov ecx, create_l4 - create_l1 + rep movsb + mov [var_WORD_DP], edi + mov edx, edi + call WORD_ALIGNDP + POPRSP eax + mov edi, [var_WORD_DP] + sub edx, eax + mov [eax + create_l2 - create_l1 - 4], edi + mov [eax + XT_BODY], edi + mov [eax + XT_LENGTH], edx + ret + defword_end +create_l1: + LOADTOS 0xBAADF00D +create_l2: + call strict near create_l3 +create_l3: + ret +create_l4: + + defword "dodoes", 0, WORD_DODOES, WORD_CALL_COMMA + call WORD_LATEST + call WORD_FETCH + call WORD_TCFA + add ebx, create_l3 - create_l1 - 4 + POPDSP eax + sub eax, ebx + sub eax, 4 + mov [ebx], eax + POPDSP ebx + ret + defword_end + + defword "does>", F_IMMED, WORD_DOES, WORD_CALL_COMMA + call WORD_LIT_COMMA + LOADTOS [var_WORD_DP] + add ebx, 10 + call WORD_COMMA + LOADTOS WORD_DODOES + call WORD_COMPILE_COMMA + LOADTOS 0 + mov bl, [does_l1] + call WORD_CHAR_COMMA +does_l1: + ret + defword_end + + defword "postpone", F_IMMED, WORD_POSTPONE, WORD_CALL_COMMA + call WORD_PARSENAME + call WORD_FIND_DICT + mov dl, [ebx + H_NSIZE] + call WORD_TCFA + and edx, F_IMMED + if z + call WORD_LIT_COMMA + call WORD_COMMA + LOADTOS WORD_COMPILE_COMMA + endif + jmp WORD_COMPILE_COMMA + ret + defword_end + + defword "call,", 0, WORD_CALL_COMMA, WORD_CALL_COMMA + mov edi, [var_WORD_DP] + mov [lastcall], edi ; record last location of last call + mov esi, i_call + movsb + mov eax, ebx + sub eax, 4 + sub eax, edi + stosd + mov [var_WORD_DP], edi + POPDSP ebx + ret + defword_end + + defword "inline,", 0, WORD_INLINE_COMMA, WORD_CALL_COMMA + mov ecx, [ebx + XT_LENGTH] + dec ecx ; actual code length minus ret + mov esi, ebx + mov edi, [var_WORD_DP] + rep movsb ; inline copy the code + mov [var_WORD_DP], edi ; update DP + POPDSP ebx + ret + defword_end + + defword "compile,", 0, WORD_COMPILE_COMMA, WORD_INLINE_COMMA + call [ebx + XT_COMPILE] + ret + defword_end + + defword ";", F_IMMED, WORD_SEMICOLON, WORD_CALL_COMMA + LOADTOS WORD_EXIT +i_call: + call strict near WORD_COMPILE_COMMA + call WORD_LATEST + call WORD_FETCH + call WORD_HIDDEN ; toggle hidden flag -- unhide the word (see below for definition). + call WORD_LBRAC ; go back to IMMEDIATE mode. + mov edx, ebx + mov ebx, [var_WORD_LATEST] + call WORD_TCFA + mov ecx, [var_WORD_DP] + sub ecx, ebx + mov [ebx + XT_LENGTH], ecx ; set code size of word + mov ebx, edx + ret + defword_end + + defword "immediate", 0, WORD_IMMEDIATE, WORD_CALL_COMMA + mov edi, [var_WORD_LATEST] ; LATEST word. + add edi, H_NSIZE ; Point to name/flags byte. + xor byte [edi], F_IMMED ; Toggle the IMMED bit. + ret + defword_end + + defword "hidden", 0, WORD_HIDDEN, WORD_CALL_COMMA + add ebx, H_NSIZE ; Point to name/flags byte. + xor byte [ebx], F_HIDDEN ; Toggle the HIDDEN bit. + POPDSP ebx + ret + defword_end + + defword "[", F_IMMED, WORD_LBRAC, WORD_CALL_COMMA + mov long [var_WORD_STATE], 0 ; Set STATE to 0. + ret + defword_end + + defword "]", 0, WORD_RBRAC, WORD_CALL_COMMA + mov long [var_WORD_STATE], 1 ; Set STATE to 1. + ret + defword_end + +;;;;;;;;;;;;;;;;;;;;; +; source buffer words +;;;;;;;;;;;;;;;;;;;;; + + defword "source", 0, WORD_SOURCE, WORD_CALL_COMMA + call WORD_INHASH + call WORD_FETCH2 + ret + defword_end + + defword "refill", 0, WORD_REFILL, WORD_CALL_COMMA + LOADTOS tib_buffer + call WORD_LINESIZE ; ( tib len ) + call WORD_OVER + call WORD_SWAP ; ( tib tib len ) + call WORD_ACCEPT ; read line into TIB + call WORD_DUP2 + call WORD_TABSTOSPACES + call WORD_INHASH + call WORD_STORE2 ; set as current WORD_SOURCE + LOADTOS 0 + call WORD_TOIN + call WORD_STORE ; set to start of buffer + LOADTOS -1 + ret + defword_end + + defword "isspace?", 0, WORD_ISSPACE, WORD_CALL_COMMA + LOADTOS ' ' + call WORD_ULTEQ + ret + defword_end + + defword "isnotspace?", 0, WORD_ISNOTSPACE, WORD_CALL_COMMA + call WORD_ISSPACE + call WORD_ZEQ + ret + defword_end + + defword "xt-skip", 0, WORD_XTSKIP, WORD_CALL_COMMA + TORSP +xtskip_l1: + test ebx, ebx + jz xtskip_l3 + call WORD_OVER + call WORD_FETCHBYTE + FETCHRSP + call WORD_EXECUTE + test ebx, ebx + jz xtskip_l2 + mov ebx, 1 + call WORD_SSTRING + jmp xtskip_l1 +xtskip_l2: + call WORD_DROP +xtskip_l3: + ADDRSP 4 + ret + defword_end + +;;;;;;;;;;;;;;;;;;;;;; +; input parseing words +;;;;;;;;;;;;;;;;;;;;;; + + defword "parse-name", 0, WORD_PARSENAME, WORD_CALL_COMMA + call WORD_SOURCE + call WORD_TOIN + call WORD_FETCH + call WORD_SSTRING + LOADTOS WORD_ISSPACE + call WORD_XTSKIP + call WORD_OVER + TORSP + LOADTOS WORD_ISNOTSPACE + call WORD_XTSKIP + call WORD_DUP2 + LOADTOS 1 + call WORD_MIN + call WORD_ADD + call WORD_SOURCE + call WORD_DROP + call WORD_SUB + call WORD_TOIN + call WORD_STORE + call WORD_DROP + FROMRSP + call WORD_TUCK + call WORD_SUB +; code to print out "P CR" +;LOADTOS 80 +;call WORD_EMIT +;LOADTOS 32 +;call WORD_EMIT +;call WORD_DUP2 +;call WORD_TYPE +;LOADTOS 10 +;call WORD_EMIT + ret + defword_end + + defword "word-name", 0, WORD_WORDNAME, WORD_CALL_COMMA + call WORD_PARSENAME ; ( start len ) + LOADTOS word_buf ; ( string size buf ) + call WORD_DUP2 ; ( string size buf size buf ) + call WORD_STOREBYTE ; ( string size buf ) + call WORD_INCR ; ( string size buf+1 ) + call WORD_SWAP ; ( string buf+1 size ) + call WORD_CMOVE + LOADTOS word_buf ; ( cstring ) +; debug code to print out "N CR" +;LOADTOS 78 +;call WORD_EMIT +;LOADTOS 32 +;call WORD_EMIT +;call WORD_DUP2 +;call WORD_TYPE +;LOADTOS 10 +;call WORD_EMIT + ret + defword_end + + defword "interp-name", 0, WORD_INTERPNAME, WORD_CALL_COMMA + call WORD_PARSENAME ; ( start len ) + LOADTOS intep_name_buf ; ( string size buf ) + call WORD_DUP2 ; ( string size buf size buf ) + call WORD_STOREBYTE ; ( string size buf ) + call WORD_INCR ; ( string size buf+1 ) + call WORD_SWAP ; ( string buf+1 size ) + call WORD_CMOVE + LOADTOS intep_name_buf ;( cstring ) + ret + defword_end + + defword "interpret", 0, WORD_INTERPRET, WORD_CALL_COMMA + loopstart + call WORD_INTERPNAME + mov al, [ebx] + test al, al + breakif z + ; debug code to print out "I CR" + ;LOADTOS 73 + ;call WORD_EMIT + ;LOADTOS 32 + ;call WORD_EMIT + ;call WORD_DUP + ;call WORD_COUNT + ;call WORD_TYPE + ;LOADTOS 10 + ;call WORD_EMIT + call WORD_INTERP + loopend + call WORD_DROP + ret + defword_end + + defword "interp", 0, WORD_INTERP, WORD_CALL_COMMA + call WORD_FIND ; ( cstring 0 | xt 1 | xt | -1 ) + mov eax, ebx + POPDSP ebx + test eax, eax + jz tryasnumber + jle nonimediate +executeword: + mov eax, ebx + POPDSP ebx + jmp eax +nonimediate: + mov eax, [var_WORD_STATE] + test eax, eax ; are we in imedeate mode ? + jz executeword + jmp WORD_COMPILE_COMMA ; compile xt +tryasnumber: + call WORD_COUNT ; ( adr len ) + LOADTOS 0 + LOADTOS 0 + call WORD_SWAP2 ; ( 0d addr len ) + call WORD_TOSNUMBER ; ( d addr len ) + test ebx, ebx + jnz parseproblem + call WORD_DROP2 + call WORD_DROP ; ( num ) + mov eax, [var_WORD_STATE] + test eax, eax + if nz + call WORD_LIT_COMMA ; compile LIT + call WORD_COMMA ; compile value + endif + ret +parseproblem: + LOADTOS errmsg + LOADTOS errmsgend - errmsg + LOADTOS 2 + call WORD_TYPE_FD + LOADTOS errmsgnl + LOADTOS 1 + LOADTOS 2 + call WORD_TYPE_FD + LOADTOS tib_buffer + LOADTOS [var_WORD_TOIN] + LOADTOS 2 + call WORD_TYPE_FD + LOADTOS errmsgnl + LOADTOS 1 + LOADTOS 2 + call WORD_TYPE_FD + call WORD_DROP2 + call WORD_DROP2 + ret + defword_end + + defword ">number", 0, WORD_TONUMBER, WORD_CALL_COMMA + call WORD_OVER + call WORD_ADD + call WORD_SWAP ; ( ud end cur ) +tonumber_l1: + PICKDSP eax, 0 + cmp ebx, eax + jz near tonumber_l4 + call WORD_DUP + call WORD_FETCHBYTE ; ( ud end cur char ) + to_lower ebx + sub ebx, byte '0' + jb tonumber_l3 ; < '0'? + cmp ebx, byte 10 + jb tonumber_l2 ; <= '9' ? + sub ebx, byte 'a' - '0' + jb tonumber_l3 ; < 'a' ? + add ebx, byte 10 +tonumber_l2: + cmp ebx, [var_WORD_BASE] + jge tonumber_l3 ; >= WORD_BASE ? + TORSP + call WORD_SWAP2 ; ( end cur ud ) + LOADTOS [var_WORD_BASE] + call WORD_DMULSTAR + FROMRSP + call WORD_MPLUS ; ( end cur ud' ) + call WORD_SWAP2 + call WORD_INCR ; ( ud' end cur' ) + jmp tonumber_l1 +tonumber_l3: + call WORD_DROP +tonumber_l4: + call WORD_SWAP + call WORD_OVER + call WORD_SUB ; ( ud' c-addr u2 ) + ret + defword_end + + defword ">snumber", 0, WORD_TOSNUMBER, WORD_CALL_COMMA + test ebx, ebx + if nz + PICKDSP eax, 0 + mov cl, [eax] + cmp cl, '-' + jnz WORD_TONUMBER ; not '-' + inc eax + PUTDSP eax, 0 + dec ebx + call WORD_TONUMBER + call WORD_SWAP2 + call WORD_DNEGATE + call WORD_SWAP2 + endif + ret + defword_end + +;;;;;;;;;;; +; tick word +;;;;;;;;;;; + + defword "ticks", 0, WORD_TICKS, WORD_CALL_COMMA + sub ebp, byte 8 + rdtsc + mov [byte ebp -4], ebx + mov [ebp], eax + mov ebx, edx + ret + defword_end + +;;;;;;;;;;; +; test word +;;;;;;;;;;; + + defword "test", 0, WORD_TEST, WORD_CALL_COMMA + ret + defword_end + +;;;;;;;;;;;;;;;;; +; read/write data +;;;;;;;;;;;;;;;;; + + align 4 +syscallret: + ; return address saved by syscall + dd 0 +lastcall: + ; last call layed down by compiler + dd 0 + +tib_buffer: + ; keyboard input buffer + times MAX_LINE_SIZE db 0 +word_buf: + ; static buffer where WORD returns. Subsequent calls + ; overwrite this buffer. + times MAX_LINE_SIZE db 0 +intep_name_buf: + ; static buffer where INTERPNAME returns. Subsequent calls + ; overwrite this buffer. + times MAX_LINE_SIZE db 0 +emit_scratch: + ; scratch used by EMIT + db 0 +errmsg: + db "PARSE ERROR:" +errmsgend: +errmsgnl: + db 10 +bootfile: + db "forth.f" + db 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; dictionary hash table (64) +;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 4 +hash_buckets: + dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; addresses of all built in dictionary words. +; this ends up as part of the user space after booting ! +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 4 +dictionary_start: + dd dic_WORD_ABS + dd dic_WORD_ACCEPT + dd dic_WORD_ADD + dd dic_WORD_ADDBYTE + dd dic_WORD_ADDSTORE + dd dic_WORD_ALIGNDP + dd dic_WORD_AND + dd dic_WORD_BASE + dd dic_WORD_BLANK + dd dic_WORD_BLK + dd dic_WORD_BRANCH + dd dic_WORD_BUCKET + dd dic_WORD_CALL_COMMA + dd dic_WORD_CHARBUF + dd dic_WORD_CHAR_COMMA + dd dic_WORD_CLITS + dd dic_WORD_CMOVE + dd dic_WORD_CMOVEB + dd dic_WORD_COLON + dd dic_WORD_COMMA + dd dic_WORD_COMPARE + dd dic_WORD_COMPAREI + dd dic_WORD_COMPILE_COMMA + dd dic_WORD_COUNT + dd dic_WORD_CREATE + dd dic_WORD_D2SLASH + dd dic_WORD_D2STAR + dd dic_WORD_DABS + dd dic_WORD_DECR + dd dic_WORD_DECR2 + dd dic_WORD_DECR4 + dd dic_WORD_DEQ + dd dic_WORD_DIV + dd dic_WORD_DIVMOD + dd dic_WORD_DLT + dd dic_WORD_DMAX + dd dic_WORD_DMIN + dd dic_WORD_DMINUS + dd dic_WORD_DMULSTAR + dd dic_WORD_DNEGATE + dd dic_WORD_DNEQ + dd dic_WORD_DODOES + dd dic_WORD_DOES + dd dic_WORD_DP + dd dic_WORD_DPLUS + dd dic_WORD_DROP + dd dic_WORD_DROP2 + dd dic_WORD_DSPFETCH + dd dic_WORD_DSPSTORE + dd dic_WORD_DTOS + dd dic_WORD_DULT + dd dic_WORD_DUP + dd dic_WORD_DUP2 + dd dic_WORD_DZEQ + dd dic_WORD_DZLT + dd dic_WORD_DZNEQ + dd dic_WORD_EMIT + dd dic_WORD_EQ + dd dic_WORD_ERASE + dd dic_WORD_EXECUTE + dd dic_WORD_EXIT + dd dic_WORD_FETCH + dd dic_WORD_FETCH2 + dd dic_WORD_FETCHBYTE + dd dic_WORD_FETCHSHORT + dd dic_WORD_FILL + dd dic_WORD_FIND + dd dic_WORD_FIND_DICT + dd dic_WORD_FMDIVMOD + dd dic_WORD_FROMR + dd dic_WORD_FROMR2 + dd dic_WORD_GT + dd dic_WORD_GTEQ + dd dic_WORD_HEADER_COMMA + dd dic_WORD_HIDDEN + dd dic_WORD_IMMEDIATE + dd dic_WORD_INCR + dd dic_WORD_INCR2 + dd dic_WORD_INCR4 + dd dic_WORD_INHASH + dd dic_WORD_INLINE_COMMA + dd dic_WORD_INTERP + dd dic_WORD_INTERPNAME + dd dic_WORD_INTERPRET + dd dic_WORD_INVERT + dd dic_WORD_ISNOTSPACE + dd dic_WORD_ISSPACE + dd dic_WORD_KEY + dd dic_WORD_LATEST + dd dic_WORD_LBRAC + dd dic_WORD_LINESIZE + dd dic_WORD_LIT_COMMA + dd dic_WORD_LSHIFT + dd dic_WORD_LSYSCALL + dd dic_WORD_LT + dd dic_WORD_LTEQ + dd dic_WORD_MAX + dd dic_WORD_MIN + dd dic_WORD_MMINUS + dd dic_WORD_MOD + dd dic_WORD_MOVE + dd dic_WORD_MPLUS + dd dic_WORD_MSLASH + dd dic_WORD_MULDIV + dd dic_WORD_MULL + dd dic_WORD_MULSTAR + dd dic_WORD_NE + dd dic_WORD_NEGATE + dd dic_WORD_NFROMR + dd dic_WORD_NIP + dd dic_WORD_NIP2 + dd dic_WORD_NQDUP + dd dic_WORD_NROT + dd dic_WORD_NTOR + dd dic_WORD_OR + dd dic_WORD_OVER + dd dic_WORD_OVER2 + dd dic_WORD_O_APPEND + dd dic_WORD_O_CREAT + dd dic_WORD_O_EXCL + dd dic_WORD_O_NONBLOCK + dd dic_WORD_O_RDONLY + dd dic_WORD_O_RDWR + dd dic_WORD_O_TRUNC + dd dic_WORD_O_WRONLY + dd dic_WORD_PARSENAME + dd dic_WORD_PICK + dd dic_WORD_POSTPONE + dd dic_WORD_QDUP + dd dic_WORD_RBRAC + dd dic_WORD_RDROP + dd dic_WORD_RDROP2 + dd dic_WORD_READCHAR + dd dic_WORD_READLINE + dd dic_WORD_REFILL + dd dic_WORD_RFETCH + dd dic_WORD_RFETCH2 + dd dic_WORD_ROT + dd dic_WORD_ROT2 + dd dic_WORD_RSHIFT + dd dic_WORD_RSPFETCH + dd dic_WORD_RSPSTORE + dd dic_WORD_RSTORE + dd dic_WORD_RZ + dd dic_WORD_SEMICOLON + dd dic_WORD_SLITS + dd dic_WORD_SMDIVREM + dd dic_WORD_SOURCE + dd dic_WORD_SOURCEFD + dd dic_WORD_SSTRING + dd dic_WORD_STARSMOD + dd dic_WORD_STATE + dd dic_WORD_STOD + dd dic_WORD_STORE + dd dic_WORD_STORE2 + dd dic_WORD_STOREBYTE + dd dic_WORD_STORESHORT + dd dic_WORD_SUB + dd dic_WORD_SUBSTORE + dd dic_WORD_SWAP + dd dic_WORD_SWAP2 + dd dic_WORD_SYSCALL + dd dic_WORD_SYS_CLOSE + dd dic_WORD_SYS_EXIT + dd dic_WORD_SYS_FSTAT + dd dic_WORD_SYS_FSYNC + dd dic_WORD_SYS_FTRUNCATE + dd dic_WORD_SYS_LSEEK + dd dic_WORD_SYS_OPEN + dd dic_WORD_SYS_READ + dd dic_WORD_SYS_RENAME + dd dic_WORD_SYS_STAT + dd dic_WORD_SYS_UNLINK + dd dic_WORD_SYS_WRITE + dd dic_WORD_SZ + dd dic_WORD_TABSTOSPACES + dd dic_WORD_TCFA + dd dic_WORD_TICKS + dd dic_WORD_TOIN + dd dic_WORD_TONUMBER + dd dic_WORD_TOR + dd dic_WORD_TOR2 + dd dic_WORD_TOSNUMBER + dd dic_WORD_TRAILING + dd dic_WORD_TUCK + dd dic_WORD_TUCK2 + dd dic_WORD_TWODIV + dd dic_WORD_TWOMUL + dd dic_WORD_TYPE + dd dic_WORD_TYPE_FD + dd dic_WORD_UDIVMOD + dd dic_WORD_UGT + dd dic_WORD_UGTEQ + dd dic_WORD_ULT + dd dic_WORD_ULTEQ + dd dic_WORD_UMDIVMOD + dd dic_WORD_UMULSTAR + dd dic_WORD_UNUSED + dd dic_WORD_VERSION + dd dic_WORD_WORDBUF + dd dic_WORD_WORDNAME + dd dic_WORD_XOR + dd dic_WORD_XTSKIP + dd dic_WORD_ZBRANCH + dd dic_WORD_ZEQ + dd dic_WORD_ZGT + dd dic_WORD_ZGTEQ + dd dic_WORD_ZLT + dd dic_WORD_ZLTEQ + dd dic_WORD_ZNE + dd dic_WORD__F_HIDDEN + dd dic_WORD__F_IMMED + dd dic_WORD__F_LENMASK + dd dic_WORD__H_NAME + dd dic_WORD__H_NSIZE + dd dic_WORD__XT_BODY + dd dic_WORD__XT_COMPILE + dd dic_WORD__XT_LENGTH + dd dic_WORD__XT_SIZE + dd dic_WORD_TEST +dictionary_end: + +;;;;;;;;;;;;;;;;;;;;;;;;;; +; room for user dictionary +;;;;;;;;;;;;;;;;;;;;;;;;;; + + times USER_DEFS_SIZE db 0 +forth_end: diff --git a/samples/BitBake/gstreamer-libav.bb b/samples/BitBake/gstreamer-libav.bb new file mode 100644 index 00000000..803bcf2f --- /dev/null +++ b/samples/BitBake/gstreamer-libav.bb @@ -0,0 +1,25 @@ +include gstreamer1.0-libav.inc + +LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \ + file://COPYING.LIB;md5=6762ed442b3822387a51c92d928ead0d \ + file://ext/libav/gstav.h;beginline=1;endline=18;md5=a752c35267d8276fd9ca3db6994fca9c \ + file://gst-libs/ext/libav/LICENSE;md5=23a54f59b82572c203a559346e89ed57 \ + file://gst-libs/ext/libav/COPYING.GPLv2;md5=b234ee4d69f5fce4486a80fdaf4a4263 \ + file://gst-libs/ext/libav/COPYING.GPLv3;md5=d32239bcb673463ab874e80d47fae504 \ + file://gst-libs/ext/libav/COPYING.LGPLv2.1;md5=bd7a443320af8c812e4c18d1b79df004 \ + file://gst-libs/ext/libav/COPYING.LGPLv3;md5=e6a600fd5e1d9cbde2d983680233ad02" + +SRC_URI = " \ + http://gstreamer.freedesktop.org/src/gst-libav/gst-libav-${PV}.tar.xz \ + file://0001-Disable-yasm-for-libav-when-disable-yasm.patch \ + " +SRC_URI[md5sum] = "86540dee14d31daf976eb2713f2294f3" +SRC_URI[sha256sum] = "585eb7971006100ad771a852e07bd2f3e23bcc6eb0b1253a40b5a0e40e4e7418" + +LIBAV_EXTRA_CONFIGURE_COMMON_ARG = "--target-os=linux \ + --cc='${CC}' --as='${CC}' --ld='${CC}' --nm='${NM}' --ar='${AR}' \ + --ranlib='${RANLIB}' \ + ${GSTREAMER_1_0_DEBUG}" + +S = "${WORKDIR}/gst-libav-${PV}" + diff --git a/samples/BitBake/qtbase-native.bb b/samples/BitBake/qtbase-native.bb new file mode 100644 index 00000000..5d24f48a --- /dev/null +++ b/samples/BitBake/qtbase-native.bb @@ -0,0 +1,13 @@ +require qt5-git.inc +require ${PN}.inc + +do_install_append() { + # for modules which are still using syncqt and call qtPrepareTool(QMAKE_SYNCQT, syncqt) + # e.g. qt3d, qtwayland + ln -sf syncqt.pl ${D}${OE_QMAKE_PATH_QT_BINS}/syncqt +} + +QT_MODULE_BRANCH = "release" +# v5.2.1 + 168 commits +SRCREV = "08cbbde61778276ccdda73d89fd64d02c623779f" + diff --git a/samples/C#/AssemblyInfo.cs b/samples/C#/AssemblyInfo.cs new file mode 100644 index 00000000..1ef68427 --- /dev/null +++ b/samples/C#/AssemblyInfo.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("Simple")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] diff --git a/samples/C#/BsonPropertyValue.cs b/samples/C#/BsonPropertyValue.cs new file mode 100644 index 00000000..94d27c88 --- /dev/null +++ b/samples/C#/BsonPropertyValue.cs @@ -0,0 +1,20 @@ +using System; + +namespace MongoDB.Serialization.Descriptors +{ + internal class BsonPropertyValue + { + public bool IsDictionary { get; private set; } + + public Type Type { get; private set; } + + public object Value { get; private set; } + + public BsonPropertyValue(Type type, object value, bool isDictionary) + { + Type = type; + Value = value; + IsDictionary = isDictionary; + } + } +} \ No newline at end of file diff --git a/samples/C#/MongoExpressionVisitor.cs b/samples/C#/MongoExpressionVisitor.cs new file mode 100644 index 00000000..b7a1effe --- /dev/null +++ b/samples/C#/MongoExpressionVisitor.cs @@ -0,0 +1,153 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Linq.Expressions; + +namespace MongoDB.Linq.Expressions +{ + internal class MongoExpressionVisitor : ExpressionVisitor + { + protected override Expression Visit(Expression exp) + { + if (exp == null) + return null; + switch ((MongoExpressionType)exp.NodeType) + { + case MongoExpressionType.Collection: + return VisitCollection((CollectionExpression)exp); + case MongoExpressionType.Field: + return VisitField((FieldExpression)exp); + case MongoExpressionType.Projection: + return VisitProjection((ProjectionExpression)exp); + case MongoExpressionType.Select: + return VisitSelect((SelectExpression)exp); + case MongoExpressionType.Aggregate: + return VisitAggregate((AggregateExpression)exp); + case MongoExpressionType.AggregateSubquery: + return VisitAggregateSubquery((AggregateSubqueryExpression)exp); + case MongoExpressionType.Scalar: + return VisitScalar((ScalarExpression)exp); + default: + return base.Visit(exp); + } + } + + protected virtual Expression VisitAggregate(AggregateExpression aggregate) + { + var exp = Visit(aggregate.Argument); + if (exp != aggregate.Argument) + return new AggregateExpression(aggregate.Type, aggregate.AggregateType, exp, aggregate.Distinct); + + return aggregate; + } + + protected virtual Expression VisitAggregateSubquery(AggregateSubqueryExpression aggregateSubquery) + { + Expression e = Visit(aggregateSubquery.AggregateAsSubquery); + ScalarExpression subquery = (ScalarExpression)e; + if (subquery != aggregateSubquery.AggregateAsSubquery) + return new AggregateSubqueryExpression(aggregateSubquery.GroupByAlias, aggregateSubquery.AggregateInGroupSelect, subquery); + return aggregateSubquery; + } + + protected virtual Expression VisitCollection(CollectionExpression collection) + { + return collection; + } + + protected virtual Expression VisitField(FieldExpression field) + { + var e = Visit(field.Expression); + if (field.Expression != e) + field = new FieldExpression(e, field.Alias, field.Name); + + return field; + } + + protected virtual Expression VisitProjection(ProjectionExpression projection) + { + var source = (SelectExpression)Visit(projection.Source); + var projector = Visit(projection.Projector); + if (source != projection.Source || projector != projection.Projector) + return new ProjectionExpression(source, projector, projection.Aggregator); + return projection; + } + + protected ReadOnlyCollection VisitOrderBy(ReadOnlyCollection orderBys) + { + if (orderBys != null) + { + List alternate = null; + for (int i = 0, n = orderBys.Count; i < n; i++) + { + OrderExpression expr = orderBys[i]; + Expression e = this.Visit(expr.Expression); + if (alternate == null && e != expr.Expression) + alternate = orderBys.Take(i).ToList(); + if (alternate != null) + alternate.Add(new OrderExpression(expr.OrderType, e)); + } + if (alternate != null) + return alternate.AsReadOnly(); + } + return orderBys; + } + + protected virtual Expression VisitScalar(ScalarExpression scalar) + { + SelectExpression select = (SelectExpression)Visit(scalar.Select); + if (select != scalar.Select) + return new ScalarExpression(scalar.Type, select); + return scalar; + } + + protected virtual Expression VisitSelect(SelectExpression select) + { + var from = VisitSource(select.From); + var where = Visit(select.Where); + var groupBy = Visit(select.GroupBy); + var orderBy = VisitOrderBy(select.OrderBy); + var skip = Visit(select.Skip); + var take = Visit(select.Take); + var fields = VisitFieldDeclarationList(select.Fields); + if (from != select.From || where != select.Where || orderBy != select.OrderBy || groupBy != select.GroupBy || skip != select.Skip || take != select.Take || fields != select.Fields) + return new SelectExpression(select.Alias, fields, from, where, orderBy, groupBy, select.IsDistinct, skip, take); + return select; + } + + protected virtual Expression VisitSource(Expression source) + { + return Visit(source); + } + + protected virtual Expression VisitSubquery(SubqueryExpression subquery) + { + switch ((MongoExpressionType)subquery.NodeType) + { + case MongoExpressionType.Scalar: + return VisitScalar((ScalarExpression)subquery); + } + return subquery; + } + + protected virtual ReadOnlyCollection VisitFieldDeclarationList(ReadOnlyCollection fields) + { + if (fields == null) + return fields; + + List alternate = null; + for (int i = 0, n = fields.Count; i < n; i++) + { + var f = fields[i]; + var e = Visit(f.Expression); + if (f.Expression != e && alternate == null) + alternate = fields.Take(i).ToList(); + if (alternate != null) + alternate.Add(new FieldDeclaration(f.Name, e)); + } + if (alternate != null) + return alternate.AsReadOnly(); + return fields; + } + } +} \ No newline at end of file diff --git a/samples/C++/16F88.h b/samples/C++/16F88.h new file mode 100644 index 00000000..28f51ce4 --- /dev/null +++ b/samples/C++/16F88.h @@ -0,0 +1,86 @@ +/* + * This file is part of PIC + * Copyright © 2012 Rachel Mant (dx-mon@users.sourceforge.net) + * + * PIC is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PIC is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +enum PIC16F88Instruction +{ + ADDWF, + ANDWF, + CLRF, + CLRW, + COMF, + DECF, + DECFSZ, + INCF, + INCFSZ, + IORWF, + MOVF, + MOVWF, + NOP, + RLF, + RRF, + SUBWF, + SWAPF, + XORWF, + BCF, + BSF, + BTFSC, + BTFSS, + ADDLW, + ANDLW, + CALL, + CLRWDT, + GOTO, + IORLW, + MOVLW, + RETFIE, + RETLW, + RETURN, + SLEEP, + SUBLW, + XORLW +}; + +class PIC16F88 +{ +public: + PIC16F88(ROM *ProgramMemory); + void Step(); + +private: + uint8_t q; + bool nextIsNop, trapped; + Memory *memory; + ROM *program; + Stack *CallStack; + Register *PC; + Register<> *WREG, *PCL, *STATUS, *PCLATCH; + PIC16F88Instruction inst; + uint16_t instrWord; + +private: + void DecodeInstruction(); + void ProcessInstruction(); + + uint8_t GetBank(); + uint8_t GetMemoryContents(uint8_t partialAddress); + void SetMemoryContents(uint8_t partialAddress, uint8_t newVal); + void CheckZero(uint8_t value); + void StoreValue(uint8_t value, bool updateZero); + uint8_t SetCarry(bool val); + uint16_t GetPCHFinalBits(); +}; diff --git a/samples/C++/Entity.h b/samples/C++/Entity.h new file mode 100644 index 00000000..619fc1d1 --- /dev/null +++ b/samples/C++/Entity.h @@ -0,0 +1,98 @@ +/** +* @file Entity.h +* @page EntityPage Entity +* @brief represent an entity in the game +* @author vinz243 +* @version 0.1.0 +* This file represents an Entity in the game system +* This parent type is a static entity which is shown and loaded into the Physics engine but never updated +*/ + +#ifndef ENTITY_H +#define ENTITY_H + +#include "base.h" +/// @namespace Whitedrop +namespace Whitedrop { + /** @class Entity + * This parent type is a static entity which is shown and loaded into the Physics engine but never updated + */ + class Entity { + public: + /** + * @brief Create static entity + * @details creates a static entity instance according to the mesh and the id, the position + * This needs to be attached to a World after! + * The material name is not the file name but the material name! + * @ref WorldPage + * @param mesh the name of the mesh for the object, file must be in media/meshes + * @param id an unique identifier for the object, shortest as possible + * @param dimensions an Ogre::Vector3 which contains the dimensions in meter + * @param position the Vector3 which contains it position + * @param material the material name + */ + Entity(std::string mesh, std::string id, Ogre::Vector3 dimensions, Ogre::Vector3 position, std::string material); + /** + * @brief The copy constructor + * @details A copy constr + * + * @param ref the Entity to be copied from + */ + Entity(const Entity &ref); + + /** + * @brief The assignement operator + * @details + * + * @param ent the entity to be copied + */ + Entity& operator=(const Entity ent); + + /** + * @brief destrctor + * @details + */ + virtual ~Entity(void); + + /** + * @brief a constance type of the entity + * @details depends of the class. + * May contain STATIC, DYNAMIC or ETHERAL + */ + const std::string type = "STATIC"; + + /** + * @brief Attach the entity to specified sceneManager + * @details This creates the OgreEntity using sceneMgr, + * set material, create a Node with name as `_n`, + * scale it to match dimensions and translate the node to pos + * @param sceneMgr the scene manager to use + */ + virtual void setup(Ogre::SceneManager* sceneMgr); + + /** + * @brief the update method + * @details this method should be called on each world update. + * Even though the method is necessary declared, the main impl of + * a static entity should be empty since it is not updated by physics + * However, a Dynamic entity should implement this function in order to: + * 1) Get from the physics engine the actor position in the physic world + * 2) Update the OgreEntity position and rotation from the previous actor + * @return whether it was successful or not, if falsey engine should stop + */ + virtual bool update(void); + + protected: + std::string mMesh = "cube.mesh"; + std::string mId; + std::string mMaterial; + Ogre::Vector3 mDimensions; + Ogre::Vector3 mPosition; + Ogre::Entity* mEntity; + Ogre::SceneNode* mNode; + + }; +} + + +#endif \ No newline at end of file diff --git a/samples/C++/Memory16F88.h b/samples/C++/Memory16F88.h new file mode 100644 index 00000000..ced2ef13 --- /dev/null +++ b/samples/C++/Memory16F88.h @@ -0,0 +1,32 @@ +/* + * This file is part of PIC + * Copyright © 2012 Rachel Mant (dx-mon@users.sourceforge.net) + * + * PIC is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PIC is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "Memory.h" + +class Memory16F88 : public Memory +{ +private: + uint8_t memory[512]; + std::map memoryMap; + +public: + Memory16F88(); + uint8_t Dereference(uint8_t bank, uint8_t partialAddress); + uint8_t *Reference(uint8_t bank, uint8_t partialAddress); + uint8_t *operator [](uint32_t ref); +}; diff --git a/samples/C++/ThreadedQueue.h b/samples/C++/ThreadedQueue.h new file mode 100644 index 00000000..6b2fbaad --- /dev/null +++ b/samples/C++/ThreadedQueue.h @@ -0,0 +1,76 @@ +/* + * This file is part of IRCBot + * Copyright © 2014 Rachel Mant (dx-mon@users.sourceforge.net) + * + * IRCBot is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * IRCBot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __THREADED_QUEUE_H__ +#define __THREADED_QUEUE_H__ + +#include +#include + +template +class ThreadedQueue : public std::queue +{ +private: + pthread_mutex_t queueMutex; + pthread_cond_t queueCond; + +public: + ThreadedQueue() + { + pthread_mutexattr_t mutexAttrs; + pthread_condattr_t condAttrs; + + pthread_mutexattr_init(&mutexAttrs); + pthread_mutexattr_settype(&mutexAttrs, PTHREAD_MUTEX_ERRORCHECK); + pthread_mutex_init(&queueMutex, &mutexAttrs); + pthread_mutexattr_destroy(&mutexAttrs); + + pthread_condattr_init(&condAttrs); + pthread_condattr_setpshared(&condAttrs, PTHREAD_PROCESS_PRIVATE); + pthread_cond_init(&queueCond, &condAttrs); + pthread_condattr_destroy(&condAttrs); + } + + ~ThreadedQueue() + { + pthread_cond_destroy(&queueCond); + pthread_mutex_destroy(&queueMutex); + } + + void waitItems() + { + pthread_mutex_lock(&queueMutex); + pthread_cond_wait(&queueCond, &queueMutex); + pthread_mutex_unlock(&queueMutex); + } + + void signalItems() + { + pthread_mutex_lock(&queueMutex); + pthread_cond_broadcast(&queueCond); + pthread_mutex_unlock(&queueMutex); + } + + void push(T item) + { + std::queue::push(item); + signalItems(); + } +}; + +#endif /*__THREADED_QUEUE_H__*/ diff --git a/samples/C++/qsciprinter.cp b/samples/C++/qsciprinter.cp new file mode 100644 index 00000000..f30d6454 --- /dev/null +++ b/samples/C++/qsciprinter.cp @@ -0,0 +1,116 @@ +// This module defines interface to the QsciPrinter class. +// +// Copyright (c) 2011 Riverbank Computing Limited +// +// This file is part of QScintilla. +// +// This file may be used under the terms of the GNU General Public +// License versions 2.0 or 3.0 as published by the Free Software +// Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +// included in the packaging of this file. Alternatively you may (at +// your option) use any later version of the GNU General Public +// License if such license has been publicly approved by Riverbank +// Computing Limited (or its successors, if any) and the KDE Free Qt +// Foundation. In addition, as a special exception, Riverbank gives you +// certain additional rights. These rights are described in the Riverbank +// GPL Exception version 1.1, which can be found in the file +// GPL_EXCEPTION.txt in this package. +// +// If you are unsure which license is appropriate for your use, please +// contact the sales department at sales@riverbankcomputing.com. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + +#ifndef QSCIPRINTER_H +#define QSCIPRINTER_H + +#ifdef __APPLE__ +extern "C++" { +#endif + +#include + +#include +#include + + +QT_BEGIN_NAMESPACE +class QRect; +class QPainter; +QT_END_NAMESPACE + +class QsciScintillaBase; + + +//! \brief The QsciPrinter class is a sub-class of the Qt QPrinter class that +//! is able to print the text of a Scintilla document. +//! +//! The class can be further sub-classed to alter to layout of the text, adding +//! headers and footers for example. +class QSCINTILLA_EXPORT QsciPrinter : public QPrinter +{ +public: + //! Constructs a printer paint device with mode \a mode. + QsciPrinter(PrinterMode mode = ScreenResolution); + + //! Destroys the QsciPrinter instance. + virtual ~QsciPrinter(); + + //! Format a page, by adding headers and footers for example, before the + //! document text is drawn on it. \a painter is the painter to be used to + //! add customised text and graphics. \a drawing is true if the page is + //! actually being drawn rather than being sized. \a painter drawing + //! methods must only be called when \a drawing is true. \a area is the + //! area of the page that will be used to draw the text. This should be + //! modified if it is necessary to reserve space for any customised text or + //! graphics. By default the area is relative to the printable area of the + //! page. Use QPrinter::setFullPage() because calling printRange() if you + //! want to try and print over the whole page. \a pagenr is the number of + //! the page. The first page is numbered 1. + virtual void formatPage(QPainter &painter, bool drawing, QRect &area, + int pagenr); + + //! Return the number of points to add to each font when printing. + //! + //! \sa setMagnification() + int magnification() const {return mag;} + + //! Sets the number of points to add to each font when printing to \a + //! magnification. + //! + //! \sa magnification() + virtual void setMagnification(int magnification); + + //! Print a range of lines from the Scintilla instance \a qsb. \a from is + //! the first line to print and a negative value signifies the first line + //! of text. \a to is the last line to print and a negative value + //! signifies the last line of text. true is returned if there was no + //! error. + virtual int printRange(QsciScintillaBase *qsb, int from = -1, int to = -1); + + //! Return the line wrap mode used when printing. The default is + //! QsciScintilla::WrapWord. + //! + //! \sa setWrapMode() + QsciScintilla::WrapMode wrapMode() const {return wrap;} + + //! Sets the line wrap mode used when printing to \a wmode. + //! + //! \sa wrapMode() + virtual void setWrapMode(QsciScintilla::WrapMode wmode); + +private: + int mag; + QsciScintilla::WrapMode wrap; + + QsciPrinter(const QsciPrinter &); + QsciPrinter &operator=(const QsciPrinter &); +}; + +#ifdef __APPLE__ +} +#endif + +#endif diff --git a/samples/C/2D.C b/samples/C/2D.C new file mode 100644 index 00000000..b3d45015 --- /dev/null +++ b/samples/C/2D.C @@ -0,0 +1,145 @@ +#include "2D.h" +#include + +void set_vgabasemem(void) +{ + ULONG vgabase; + SELECTOR tmp; + asm mov [tmp], ds + dpmi_get_sel_base(&vgabase, tmp); + vgabasemem = (char *)(-vgabase + 0xa0000); +} + +void drw_chdis(int mode) // change the display! +{ + regs.b.ah = 0x00; // seet theh display moode + regs.b.al = mode; // change it to the mode like innit + regs.h.flags = 0x72;// Set the dingoes kidneys out of FLAGS eh? + regs.h.ss = 0; // Like, totally set the stack segment + regs.h.sp = 0; // Set tha stack pointaaaaahhhhh!!! + dpmi_simulate_real_interrupt(0x10, ®s); +} + +void drw_pix(int x, int y, enum COLORS col) +{ + *VGAPIX(x, y) = col; +} + +void drw_line(int x0, int y0, int x1, int y1, enum COLORS col) +{ + // Going for the optimized version of bresenham's line algo. + int stp = (abs(y0 - y1) > abs(x0 - x1)); + int tmp, dx, dy, err, yi, i, j; // yi = y excrement + if (stp) { + // swappity swap + tmp = y0; + y0 = x0; + x0 = tmp; + + tmp = y1; + y1 = x1; + x1 = tmp; + } + // AAAAND NOW WE MUST DO ZEES AGAIN :( + // I'm sure there was a func somewhere that does this? :P + if (x0 > x1) { + tmp = x0; + x0 = x1; + x1 = tmp; + + tmp = y0; + y0 = y1; + y1 = tmp; + } + dx = (x1 - x0); + dy = (abs(y1 - y0)); + err = (dx / 2); + + if (y0 < y1) + yi = 1; + else + yi = -1; + j = y0; + for (i = x0; i < x1; i++) + { + if (stp) + *VGAPIX(j, i) = col; + else + *VGAPIX(i, j) = col; + + err -= dy; + if (err < 0) { + j += yi; + err += dx; + } + } +} + +void drw_rectl(int x, int y, int w, int h, enum COLORS col) +{ + drw_line(x, y, x+w, y, col); + drw_line(x+w, y, x+w, y+h, col); + + drw_line(x, y, x, y+h, col); + drw_line(x, y+h, x+w+1, y+h, col); +} + +void drw_rectf(int x, int y, int w, int h, enum COLORS col) +{ + int i, j; + for (j = y; j < x+h; j++) { + for (i = x; i < y+w; i++) { + *VGAPIX(i, j) = col; + } + } +} + +void drw_circl(int x, int y, int rad, enum COLORS col) +{ + int mang, i; // max angle, haha + int px, py; + mang = 360; // Yeah yeah I'll switch to rad later + for (i = 0; i <= mang; i++) + { + px = cos(i)*rad + x; // + px; // causes some really cools effects! :D + py = sin(i)*rad + y; // + py; + *VGAPIX(px, py) = col; + } +} + +void drw_tex(int x, int y, int w, int h, enum COLORS tex[]) +{ // i*w+j + int i, j; + for (i = 0; i < w; i++) + { + for (j = 0; j < h; j++) + { + *VGAPIX(x+i, y+j) = tex[j*w+i]; + } + } +} + +void 2D_init(void) +{ + set_vgabasemem(); + drw_chdis(0x13); +} + +void 2D_exit(void) +{ + drw_chdis(3); +} +/* +int main() +{ + set_vgabasemem(); + drw_chdis(0x13); + + while(!kbhit()) { + if ((getch()) == 0x1b) // escape + break; + } + drw_chdis(3); + return 0; +} +*/ diff --git a/samples/C/2D.H b/samples/C/2D.H new file mode 100644 index 00000000..e3354986 --- /dev/null +++ b/samples/C/2D.H @@ -0,0 +1,29 @@ +#ifndef __2DGFX +#define __2DGFX +// Includes +#include +#include +#include +#include + +// Defines +#define VGAPIX(x,y) (vgabasemem + (x) + (y) * 320) + +// Variables +char * vgabasemem; +DPMI_REGS regs; + +// Drawing functions: +//void setvgabasemem(void); +void drw_chdis(int mode); // draw_func_change_display +void drw_pix(int x, int y, enum COLORS col); +void drw_line(int x0, int y0, int x1, int y1, enum COLORS col); +void drw_rectl(int x, int y, int w, int h, enum COLORS col); +void drw_rectf(int x, int y, int w, int h, enum COLORS col); +void drw_cirl(int x, int y, int rad, enum COLORS col); +void drw_tex(int x, int y, int w, int h, enum COLORS tex[]); +void 2D_init(void); +void 2D_exit(void); + + +#endif diff --git a/samples/C/ArrowLeft.h b/samples/C/ArrowLeft.h new file mode 100644 index 00000000..b3577c0e --- /dev/null +++ b/samples/C/ArrowLeft.h @@ -0,0 +1,93 @@ +/* + * This file is part of GTK++ (libGTK++) + * Copyright © 2012 Rachel Mant (dx-mon@users.sourceforge.net) + * + * GTK++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GTK++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +/* GdkPixbuf RGBA C-Source image dump */ + +#ifdef __SUNPRO_C +#pragma align 4 (ArrowLeft) +#endif +#ifdef __GNUC__ +static const uint8_t ArrowLeft[] __attribute__ ((__aligned__ (4))) = +#else +static const uint8_t ArrowLeft[] = +#endif +{ "" + /* Pixbuf magic (0x47646b50) */ + "GdkP" + /* length: header (24) + pixel_data (1600) */ + "\0\0\6X" + /* pixdata_type (0x1010002) */ + "\1\1\0\2" + /* rowstride (80) */ + "\0\0\0P" + /* width (20) */ + "\0\0\0\24" + /* height (20) */ + "\0\0\0\24" + /* pixel_data: */ + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377" + "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" + "\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0" + "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0"}; + + diff --git a/samples/C/GLKMatrix4.h b/samples/C/GLKMatrix4.h new file mode 100644 index 00000000..41eb5afd --- /dev/null +++ b/samples/C/GLKMatrix4.h @@ -0,0 +1,903 @@ +// +// GLKMatrix4.h +// GLKit +// +// Copyright (c) 2011, Apple Inc. All rights reserved. +// + +#ifndef __GLK_MATRIX_4_H +#define __GLK_MATRIX_4_H + +#include +#include +#include + +#if defined(__ARM_NEON__) +#include +#endif + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma mark - +#pragma mark Prototypes +#pragma mark - + +extern const GLKMatrix4 GLKMatrix4Identity; + +/* + m30, m31, and m32 correspond to the translation values tx, ty, tz, respectively. + */ +static __inline__ GLKMatrix4 GLKMatrix4Make(float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33); + +/* + m03, m13, and m23 correspond to the translation values tx, ty, tz, respectively. + */ +static __inline__ GLKMatrix4 GLKMatrix4MakeAndTranspose(float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33); + +/* + m[12], m[13], and m[14] correspond to the translation values tx, ty, and tz, respectively. + */ +static __inline__ GLKMatrix4 GLKMatrix4MakeWithArray(float values[16]); + +/* + m[3], m[7], and m[11] correspond to the translation values tx, ty, and tz, respectively. + */ +static __inline__ GLKMatrix4 GLKMatrix4MakeWithArrayAndTranspose(float values[16]); + +/* + row0, row1, and row2's last component should correspond to the translation values tx, ty, and tz, respectively. + */ +static __inline__ GLKMatrix4 GLKMatrix4MakeWithRows(GLKVector4 row0, + GLKVector4 row1, + GLKVector4 row2, + GLKVector4 row3); + +/* + column3's first three components should correspond to the translation values tx, ty, and tz. + */ +static __inline__ GLKMatrix4 GLKMatrix4MakeWithColumns(GLKVector4 column0, + GLKVector4 column1, + GLKVector4 column2, + GLKVector4 column3); + +/* + The quaternion will be normalized before conversion. + */ +static __inline__ GLKMatrix4 GLKMatrix4MakeWithQuaternion(GLKQuaternion quaternion); + +static __inline__ GLKMatrix4 GLKMatrix4MakeTranslation(float tx, float ty, float tz); +static __inline__ GLKMatrix4 GLKMatrix4MakeScale(float sx, float sy, float sz); +static __inline__ GLKMatrix4 GLKMatrix4MakeRotation(float radians, float x, float y, float z); + +static __inline__ GLKMatrix4 GLKMatrix4MakeXRotation(float radians); +static __inline__ GLKMatrix4 GLKMatrix4MakeYRotation(float radians); +static __inline__ GLKMatrix4 GLKMatrix4MakeZRotation(float radians); + +/* + Equivalent to gluPerspective. + */ +static __inline__ GLKMatrix4 GLKMatrix4MakePerspective(float fovyRadians, float aspect, float nearZ, float farZ); + +/* + Equivalent to glFrustum. + */ +static __inline__ GLKMatrix4 GLKMatrix4MakeFrustum(float left, float right, + float bottom, float top, + float nearZ, float farZ); + +/* + Equivalent to glOrtho. + */ +static __inline__ GLKMatrix4 GLKMatrix4MakeOrtho(float left, float right, + float bottom, float top, + float nearZ, float farZ); + +/* + Equivalent to gluLookAt. + */ +static __inline__ GLKMatrix4 GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ); + +/* + Returns the upper left 3x3 portion of the 4x4 matrix. + */ +static __inline__ GLKMatrix3 GLKMatrix4GetMatrix3(GLKMatrix4 matrix); +/* + Returns the upper left 2x2 portion of the 4x4 matrix. + */ +static __inline__ GLKMatrix2 GLKMatrix4GetMatrix2(GLKMatrix4 matrix); + +/* + GLKMatrix4GetRow returns vectors for rows 0, 1, and 2 whose last component will be the translation value tx, ty, and tz, respectively. + Valid row values range from 0 to 3, inclusive. + */ +static __inline__ GLKVector4 GLKMatrix4GetRow(GLKMatrix4 matrix, int row); +/* + GLKMatrix4GetColumn returns a vector for column 3 whose first three components will be the translation values tx, ty, and tz. + Valid column values range from 0 to 3, inclusive. + */ +static __inline__ GLKVector4 GLKMatrix4GetColumn(GLKMatrix4 matrix, int column); + +/* + GLKMatrix4SetRow expects that the vector for row 0, 1, and 2 will have a translation value as its last component. + Valid row values range from 0 to 3, inclusive. + */ +static __inline__ GLKMatrix4 GLKMatrix4SetRow(GLKMatrix4 matrix, int row, GLKVector4 vector); +/* + GLKMatrix4SetColumn expects that the vector for column 3 will contain the translation values tx, ty, and tz as its first three components, respectively. + Valid column values range from 0 to 3, inclusive. + */ +static __inline__ GLKMatrix4 GLKMatrix4SetColumn(GLKMatrix4 matrix, int column, GLKVector4 vector); + +static __inline__ GLKMatrix4 GLKMatrix4Transpose(GLKMatrix4 matrix); + +GLKMatrix4 GLKMatrix4Invert(GLKMatrix4 matrix, bool *isInvertible); +GLKMatrix4 GLKMatrix4InvertAndTranspose(GLKMatrix4 matrix, bool *isInvertible); + +static __inline__ GLKMatrix4 GLKMatrix4Multiply(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight); + +static __inline__ GLKMatrix4 GLKMatrix4Add(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight); +static __inline__ GLKMatrix4 GLKMatrix4Subtract(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight); + +static __inline__ GLKMatrix4 GLKMatrix4Translate(GLKMatrix4 matrix, float tx, float ty, float tz); +static __inline__ GLKMatrix4 GLKMatrix4TranslateWithVector3(GLKMatrix4 matrix, GLKVector3 translationVector); +/* + The last component of the GLKVector4, translationVector, is ignored. + */ +static __inline__ GLKMatrix4 GLKMatrix4TranslateWithVector4(GLKMatrix4 matrix, GLKVector4 translationVector); + +static __inline__ GLKMatrix4 GLKMatrix4Scale(GLKMatrix4 matrix, float sx, float sy, float sz); +static __inline__ GLKMatrix4 GLKMatrix4ScaleWithVector3(GLKMatrix4 matrix, GLKVector3 scaleVector); +/* + The last component of the GLKVector4, scaleVector, is ignored. + */ +static __inline__ GLKMatrix4 GLKMatrix4ScaleWithVector4(GLKMatrix4 matrix, GLKVector4 scaleVector); + +static __inline__ GLKMatrix4 GLKMatrix4Rotate(GLKMatrix4 matrix, float radians, float x, float y, float z); +static __inline__ GLKMatrix4 GLKMatrix4RotateWithVector3(GLKMatrix4 matrix, float radians, GLKVector3 axisVector); +/* + The last component of the GLKVector4, axisVector, is ignored. + */ +static __inline__ GLKMatrix4 GLKMatrix4RotateWithVector4(GLKMatrix4 matrix, float radians, GLKVector4 axisVector); + +static __inline__ GLKMatrix4 GLKMatrix4RotateX(GLKMatrix4 matrix, float radians); +static __inline__ GLKMatrix4 GLKMatrix4RotateY(GLKMatrix4 matrix, float radians); +static __inline__ GLKMatrix4 GLKMatrix4RotateZ(GLKMatrix4 matrix, float radians); + +/* + Assumes 0 in the w component. + */ +static __inline__ GLKVector3 GLKMatrix4MultiplyVector3(GLKMatrix4 matrixLeft, GLKVector3 vectorRight); +/* + Assumes 1 in the w component. + */ +static __inline__ GLKVector3 GLKMatrix4MultiplyVector3WithTranslation(GLKMatrix4 matrixLeft, GLKVector3 vectorRight); +/* + Assumes 1 in the w component and divides the resulting vector by w before returning. + */ +static __inline__ GLKVector3 GLKMatrix4MultiplyAndProjectVector3(GLKMatrix4 matrixLeft, GLKVector3 vectorRight); + +/* + Assumes 0 in the w component. + */ +static __inline__ void GLKMatrix4MultiplyVector3Array(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount); +/* + Assumes 1 in the w component. + */ +static __inline__ void GLKMatrix4MultiplyVector3ArrayWithTranslation(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount); +/* + Assumes 1 in the w component and divides the resulting vector by w before returning. + */ +static __inline__ void GLKMatrix4MultiplyAndProjectVector3Array(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount); + +static __inline__ GLKVector4 GLKMatrix4MultiplyVector4(GLKMatrix4 matrixLeft, GLKVector4 vectorRight); + +static __inline__ void GLKMatrix4MultiplyVector4Array(GLKMatrix4 matrix, GLKVector4 *vectors, size_t vectorCount); + +#pragma mark - +#pragma mark Implementations +#pragma mark - + +static __inline__ GLKMatrix4 GLKMatrix4Make(float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33) +{ + GLKMatrix4 m = { m00, m01, m02, m03, + m10, m11, m12, m13, + m20, m21, m22, m23, + m30, m31, m32, m33 }; + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeAndTranspose(float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33) +{ + GLKMatrix4 m = { m00, m10, m20, m30, + m01, m11, m21, m31, + m02, m12, m22, m32, + m03, m13, m23, m33 }; + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeWithArray(float values[16]) +{ + GLKMatrix4 m = { values[0], values[1], values[2], values[3], + values[4], values[5], values[6], values[7], + values[8], values[9], values[10], values[11], + values[12], values[13], values[14], values[15] }; + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeWithArrayAndTranspose(float values[16]) +{ +#if defined(__ARM_NEON__) + float32x4x4_t m = vld4q_f32(values); + return *(GLKMatrix4 *)&m; +#else + GLKMatrix4 m = { values[0], values[4], values[8], values[12], + values[1], values[5], values[9], values[13], + values[2], values[6], values[10], values[14], + values[3], values[7], values[11], values[15] }; + return m; +#endif +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeWithRows(GLKVector4 row0, + GLKVector4 row1, + GLKVector4 row2, + GLKVector4 row3) +{ + GLKMatrix4 m = { row0.v[0], row1.v[0], row2.v[0], row3.v[0], + row0.v[1], row1.v[1], row2.v[1], row3.v[1], + row0.v[2], row1.v[2], row2.v[2], row3.v[2], + row0.v[3], row1.v[3], row2.v[3], row3.v[3] }; + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeWithColumns(GLKVector4 column0, + GLKVector4 column1, + GLKVector4 column2, + GLKVector4 column3) +{ +#if defined(__ARM_NEON__) + float32x4x4_t m; + m.val[0] = vld1q_f32(column0.v); + m.val[1] = vld1q_f32(column1.v); + m.val[2] = vld1q_f32(column2.v); + m.val[3] = vld1q_f32(column3.v); + return *(GLKMatrix4 *)&m; +#else + GLKMatrix4 m = { column0.v[0], column0.v[1], column0.v[2], column0.v[3], + column1.v[0], column1.v[1], column1.v[2], column1.v[3], + column2.v[0], column2.v[1], column2.v[2], column2.v[3], + column3.v[0], column3.v[1], column3.v[2], column3.v[3] }; + return m; +#endif +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeWithQuaternion(GLKQuaternion quaternion) +{ + quaternion = GLKQuaternionNormalize(quaternion); + + float x = quaternion.q[0]; + float y = quaternion.q[1]; + float z = quaternion.q[2]; + float w = quaternion.q[3]; + + float _2x = x + x; + float _2y = y + y; + float _2z = z + z; + float _2w = w + w; + + GLKMatrix4 m = { 1.0f - _2y * y - _2z * z, + _2x * y + _2w * z, + _2x * z - _2w * y, + 0.0f, + _2x * y - _2w * z, + 1.0f - _2x * x - _2z * z, + _2y * z + _2w * x, + 0.0f, + _2x * z + _2w * y, + _2y * z - _2w * x, + 1.0f - _2x * x - _2y * y, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f }; + + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeTranslation(float tx, float ty, float tz) +{ + GLKMatrix4 m = GLKMatrix4Identity; + m.m[12] = tx; + m.m[13] = ty; + m.m[14] = tz; + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeScale(float sx, float sy, float sz) +{ + GLKMatrix4 m = GLKMatrix4Identity; + m.m[0] = sx; + m.m[5] = sy; + m.m[10] = sz; + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeRotation(float radians, float x, float y, float z) +{ + GLKVector3 v = GLKVector3Normalize(GLKVector3Make(x, y, z)); + float cos = cosf(radians); + float cosp = 1.0f - cos; + float sin = sinf(radians); + + GLKMatrix4 m = { cos + cosp * v.v[0] * v.v[0], + cosp * v.v[0] * v.v[1] + v.v[2] * sin, + cosp * v.v[0] * v.v[2] - v.v[1] * sin, + 0.0f, + cosp * v.v[0] * v.v[1] - v.v[2] * sin, + cos + cosp * v.v[1] * v.v[1], + cosp * v.v[1] * v.v[2] + v.v[0] * sin, + 0.0f, + cosp * v.v[0] * v.v[2] + v.v[1] * sin, + cosp * v.v[1] * v.v[2] - v.v[0] * sin, + cos + cosp * v.v[2] * v.v[2], + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f }; + + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeXRotation(float radians) +{ + float cos = cosf(radians); + float sin = sinf(radians); + + GLKMatrix4 m = { 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, cos, sin, 0.0f, + 0.0f, -sin, cos, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; + + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeYRotation(float radians) +{ + float cos = cosf(radians); + float sin = sinf(radians); + + GLKMatrix4 m = { cos, 0.0f, -sin, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + sin, 0.0f, cos, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; + + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeZRotation(float radians) +{ + float cos = cosf(radians); + float sin = sinf(radians); + + GLKMatrix4 m = { cos, sin, 0.0f, 0.0f, + -sin, cos, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; + + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakePerspective(float fovyRadians, float aspect, float nearZ, float farZ) +{ + float cotan = 1.0f / tanf(fovyRadians / 2.0f); + + GLKMatrix4 m = { cotan / aspect, 0.0f, 0.0f, 0.0f, + 0.0f, cotan, 0.0f, 0.0f, + 0.0f, 0.0f, (farZ + nearZ) / (nearZ - farZ), -1.0f, + 0.0f, 0.0f, (2.0f * farZ * nearZ) / (nearZ - farZ), 0.0f }; + + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeFrustum(float left, float right, + float bottom, float top, + float nearZ, float farZ) +{ + float ral = right + left; + float rsl = right - left; + float tsb = top - bottom; + float tab = top + bottom; + float fan = farZ + nearZ; + float fsn = farZ - nearZ; + + GLKMatrix4 m = { 2.0f * nearZ / rsl, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f * nearZ / tsb, 0.0f, 0.0f, + ral / rsl, tab / tsb, -fan / fsn, -1.0f, + 0.0f, 0.0f, (-2.0f * farZ * nearZ) / fsn, 0.0f }; + + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeOrtho(float left, float right, + float bottom, float top, + float nearZ, float farZ) +{ + float ral = right + left; + float rsl = right - left; + float tab = top + bottom; + float tsb = top - bottom; + float fan = farZ + nearZ; + float fsn = farZ - nearZ; + + GLKMatrix4 m = { 2.0f / rsl, 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f / tsb, 0.0f, 0.0f, + 0.0f, 0.0f, -2.0f / fsn, 0.0f, + -ral / rsl, -tab / tsb, -fan / fsn, 1.0f }; + + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ) +{ + GLKVector3 ev = { eyeX, eyeY, eyeZ }; + GLKVector3 cv = { centerX, centerY, centerZ }; + GLKVector3 uv = { upX, upY, upZ }; + GLKVector3 n = GLKVector3Normalize(GLKVector3Add(ev, GLKVector3Negate(cv))); + GLKVector3 u = GLKVector3Normalize(GLKVector3CrossProduct(uv, n)); + GLKVector3 v = GLKVector3CrossProduct(n, u); + + GLKMatrix4 m = { u.v[0], v.v[0], n.v[0], 0.0f, + u.v[1], v.v[1], n.v[1], 0.0f, + u.v[2], v.v[2], n.v[2], 0.0f, + GLKVector3DotProduct(GLKVector3Negate(u), ev), + GLKVector3DotProduct(GLKVector3Negate(v), ev), + GLKVector3DotProduct(GLKVector3Negate(n), ev), + 1.0f }; + + return m; +} + +static __inline__ GLKMatrix3 GLKMatrix4GetMatrix3(GLKMatrix4 matrix) +{ + GLKMatrix3 m = { matrix.m[0], matrix.m[1], matrix.m[2], + matrix.m[4], matrix.m[5], matrix.m[6], + matrix.m[8], matrix.m[9], matrix.m[10] }; + return m; +} + +static __inline__ GLKMatrix2 GLKMatrix4GetMatrix2(GLKMatrix4 matrix) +{ + GLKMatrix2 m = { matrix.m[0], matrix.m[1], + matrix.m[4], matrix.m[5] }; + return m; +} + +static __inline__ GLKVector4 GLKMatrix4GetRow(GLKMatrix4 matrix, int row) +{ + GLKVector4 v = { matrix.m[row], matrix.m[4 + row], matrix.m[8 + row], matrix.m[12 + row] }; + return v; +} + +static __inline__ GLKVector4 GLKMatrix4GetColumn(GLKMatrix4 matrix, int column) +{ +#if defined(__ARM_NEON__) + float32x4_t v = vld1q_f32(&(matrix.m[column * 4])); + return *(GLKVector4 *)&v; +#else + GLKVector4 v = { matrix.m[column * 4 + 0], matrix.m[column * 4 + 1], matrix.m[column * 4 + 2], matrix.m[column * 4 + 3] }; + return v; +#endif +} + +static __inline__ GLKMatrix4 GLKMatrix4SetRow(GLKMatrix4 matrix, int row, GLKVector4 vector) +{ + matrix.m[row] = vector.v[0]; + matrix.m[row + 4] = vector.v[1]; + matrix.m[row + 8] = vector.v[2]; + matrix.m[row + 12] = vector.v[3]; + + return matrix; +} + +static __inline__ GLKMatrix4 GLKMatrix4SetColumn(GLKMatrix4 matrix, int column, GLKVector4 vector) +{ +#if defined(__ARM_NEON__) + float *dst = &(matrix.m[column * 4]); + vst1q_f32(dst, vld1q_f32(vector.v)); + return matrix; +#else + matrix.m[column * 4 + 0] = vector.v[0]; + matrix.m[column * 4 + 1] = vector.v[1]; + matrix.m[column * 4 + 2] = vector.v[2]; + matrix.m[column * 4 + 3] = vector.v[3]; + + return matrix; +#endif +} + +static __inline__ GLKMatrix4 GLKMatrix4Transpose(GLKMatrix4 matrix) +{ +#if defined(__ARM_NEON__) + float32x4x4_t m = vld4q_f32(matrix.m); + return *(GLKMatrix4 *)&m; +#else + GLKMatrix4 m = { matrix.m[0], matrix.m[4], matrix.m[8], matrix.m[12], + matrix.m[1], matrix.m[5], matrix.m[9], matrix.m[13], + matrix.m[2], matrix.m[6], matrix.m[10], matrix.m[14], + matrix.m[3], matrix.m[7], matrix.m[11], matrix.m[15] }; + return m; +#endif +} + +static __inline__ GLKMatrix4 GLKMatrix4Multiply(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight) +{ +#if defined(__ARM_NEON__) + float32x4x4_t iMatrixLeft = *(float32x4x4_t *)&matrixLeft; + float32x4x4_t iMatrixRight = *(float32x4x4_t *)&matrixRight; + float32x4x4_t m; + + m.val[0] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[0], 0)); + m.val[1] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[1], 0)); + m.val[2] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[2], 0)); + m.val[3] = vmulq_n_f32(iMatrixLeft.val[0], vgetq_lane_f32(iMatrixRight.val[3], 0)); + + m.val[0] = vmlaq_n_f32(m.val[0], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[0], 1)); + m.val[1] = vmlaq_n_f32(m.val[1], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[1], 1)); + m.val[2] = vmlaq_n_f32(m.val[2], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[2], 1)); + m.val[3] = vmlaq_n_f32(m.val[3], iMatrixLeft.val[1], vgetq_lane_f32(iMatrixRight.val[3], 1)); + + m.val[0] = vmlaq_n_f32(m.val[0], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[0], 2)); + m.val[1] = vmlaq_n_f32(m.val[1], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[1], 2)); + m.val[2] = vmlaq_n_f32(m.val[2], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[2], 2)); + m.val[3] = vmlaq_n_f32(m.val[3], iMatrixLeft.val[2], vgetq_lane_f32(iMatrixRight.val[3], 2)); + + m.val[0] = vmlaq_n_f32(m.val[0], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[0], 3)); + m.val[1] = vmlaq_n_f32(m.val[1], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[1], 3)); + m.val[2] = vmlaq_n_f32(m.val[2], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[2], 3)); + m.val[3] = vmlaq_n_f32(m.val[3], iMatrixLeft.val[3], vgetq_lane_f32(iMatrixRight.val[3], 3)); + + return *(GLKMatrix4 *)&m; +#else + GLKMatrix4 m; + + m.m[0] = matrixLeft.m[0] * matrixRight.m[0] + matrixLeft.m[4] * matrixRight.m[1] + matrixLeft.m[8] * matrixRight.m[2] + matrixLeft.m[12] * matrixRight.m[3]; + m.m[4] = matrixLeft.m[0] * matrixRight.m[4] + matrixLeft.m[4] * matrixRight.m[5] + matrixLeft.m[8] * matrixRight.m[6] + matrixLeft.m[12] * matrixRight.m[7]; + m.m[8] = matrixLeft.m[0] * matrixRight.m[8] + matrixLeft.m[4] * matrixRight.m[9] + matrixLeft.m[8] * matrixRight.m[10] + matrixLeft.m[12] * matrixRight.m[11]; + m.m[12] = matrixLeft.m[0] * matrixRight.m[12] + matrixLeft.m[4] * matrixRight.m[13] + matrixLeft.m[8] * matrixRight.m[14] + matrixLeft.m[12] * matrixRight.m[15]; + + m.m[1] = matrixLeft.m[1] * matrixRight.m[0] + matrixLeft.m[5] * matrixRight.m[1] + matrixLeft.m[9] * matrixRight.m[2] + matrixLeft.m[13] * matrixRight.m[3]; + m.m[5] = matrixLeft.m[1] * matrixRight.m[4] + matrixLeft.m[5] * matrixRight.m[5] + matrixLeft.m[9] * matrixRight.m[6] + matrixLeft.m[13] * matrixRight.m[7]; + m.m[9] = matrixLeft.m[1] * matrixRight.m[8] + matrixLeft.m[5] * matrixRight.m[9] + matrixLeft.m[9] * matrixRight.m[10] + matrixLeft.m[13] * matrixRight.m[11]; + m.m[13] = matrixLeft.m[1] * matrixRight.m[12] + matrixLeft.m[5] * matrixRight.m[13] + matrixLeft.m[9] * matrixRight.m[14] + matrixLeft.m[13] * matrixRight.m[15]; + + m.m[2] = matrixLeft.m[2] * matrixRight.m[0] + matrixLeft.m[6] * matrixRight.m[1] + matrixLeft.m[10] * matrixRight.m[2] + matrixLeft.m[14] * matrixRight.m[3]; + m.m[6] = matrixLeft.m[2] * matrixRight.m[4] + matrixLeft.m[6] * matrixRight.m[5] + matrixLeft.m[10] * matrixRight.m[6] + matrixLeft.m[14] * matrixRight.m[7]; + m.m[10] = matrixLeft.m[2] * matrixRight.m[8] + matrixLeft.m[6] * matrixRight.m[9] + matrixLeft.m[10] * matrixRight.m[10] + matrixLeft.m[14] * matrixRight.m[11]; + m.m[14] = matrixLeft.m[2] * matrixRight.m[12] + matrixLeft.m[6] * matrixRight.m[13] + matrixLeft.m[10] * matrixRight.m[14] + matrixLeft.m[14] * matrixRight.m[15]; + + m.m[3] = matrixLeft.m[3] * matrixRight.m[0] + matrixLeft.m[7] * matrixRight.m[1] + matrixLeft.m[11] * matrixRight.m[2] + matrixLeft.m[15] * matrixRight.m[3]; + m.m[7] = matrixLeft.m[3] * matrixRight.m[4] + matrixLeft.m[7] * matrixRight.m[5] + matrixLeft.m[11] * matrixRight.m[6] + matrixLeft.m[15] * matrixRight.m[7]; + m.m[11] = matrixLeft.m[3] * matrixRight.m[8] + matrixLeft.m[7] * matrixRight.m[9] + matrixLeft.m[11] * matrixRight.m[10] + matrixLeft.m[15] * matrixRight.m[11]; + m.m[15] = matrixLeft.m[3] * matrixRight.m[12] + matrixLeft.m[7] * matrixRight.m[13] + matrixLeft.m[11] * matrixRight.m[14] + matrixLeft.m[15] * matrixRight.m[15]; + + return m; +#endif +} + +static __inline__ GLKMatrix4 GLKMatrix4Add(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight) +{ +#if defined(__ARM_NEON__) + float32x4x4_t iMatrixLeft = *(float32x4x4_t *)&matrixLeft; + float32x4x4_t iMatrixRight = *(float32x4x4_t *)&matrixRight; + float32x4x4_t m; + + m.val[0] = vaddq_f32(iMatrixLeft.val[0], iMatrixRight.val[0]); + m.val[1] = vaddq_f32(iMatrixLeft.val[1], iMatrixRight.val[1]); + m.val[2] = vaddq_f32(iMatrixLeft.val[2], iMatrixRight.val[2]); + m.val[3] = vaddq_f32(iMatrixLeft.val[3], iMatrixRight.val[3]); + + return *(GLKMatrix4 *)&m; +#else + GLKMatrix4 m; + + m.m[0] = matrixLeft.m[0] + matrixRight.m[0]; + m.m[1] = matrixLeft.m[1] + matrixRight.m[1]; + m.m[2] = matrixLeft.m[2] + matrixRight.m[2]; + m.m[3] = matrixLeft.m[3] + matrixRight.m[3]; + + m.m[4] = matrixLeft.m[4] + matrixRight.m[4]; + m.m[5] = matrixLeft.m[5] + matrixRight.m[5]; + m.m[6] = matrixLeft.m[6] + matrixRight.m[6]; + m.m[7] = matrixLeft.m[7] + matrixRight.m[7]; + + m.m[8] = matrixLeft.m[8] + matrixRight.m[8]; + m.m[9] = matrixLeft.m[9] + matrixRight.m[9]; + m.m[10] = matrixLeft.m[10] + matrixRight.m[10]; + m.m[11] = matrixLeft.m[11] + matrixRight.m[11]; + + m.m[12] = matrixLeft.m[12] + matrixRight.m[12]; + m.m[13] = matrixLeft.m[13] + matrixRight.m[13]; + m.m[14] = matrixLeft.m[14] + matrixRight.m[14]; + m.m[15] = matrixLeft.m[15] + matrixRight.m[15]; + + return m; +#endif +} + +static __inline__ GLKMatrix4 GLKMatrix4Subtract(GLKMatrix4 matrixLeft, GLKMatrix4 matrixRight) +{ +#if defined(__ARM_NEON__) + float32x4x4_t iMatrixLeft = *(float32x4x4_t *)&matrixLeft; + float32x4x4_t iMatrixRight = *(float32x4x4_t *)&matrixRight; + float32x4x4_t m; + + m.val[0] = vsubq_f32(iMatrixLeft.val[0], iMatrixRight.val[0]); + m.val[1] = vsubq_f32(iMatrixLeft.val[1], iMatrixRight.val[1]); + m.val[2] = vsubq_f32(iMatrixLeft.val[2], iMatrixRight.val[2]); + m.val[3] = vsubq_f32(iMatrixLeft.val[3], iMatrixRight.val[3]); + + return *(GLKMatrix4 *)&m; +#else + GLKMatrix4 m; + + m.m[0] = matrixLeft.m[0] - matrixRight.m[0]; + m.m[1] = matrixLeft.m[1] - matrixRight.m[1]; + m.m[2] = matrixLeft.m[2] - matrixRight.m[2]; + m.m[3] = matrixLeft.m[3] - matrixRight.m[3]; + + m.m[4] = matrixLeft.m[4] - matrixRight.m[4]; + m.m[5] = matrixLeft.m[5] - matrixRight.m[5]; + m.m[6] = matrixLeft.m[6] - matrixRight.m[6]; + m.m[7] = matrixLeft.m[7] - matrixRight.m[7]; + + m.m[8] = matrixLeft.m[8] - matrixRight.m[8]; + m.m[9] = matrixLeft.m[9] - matrixRight.m[9]; + m.m[10] = matrixLeft.m[10] - matrixRight.m[10]; + m.m[11] = matrixLeft.m[11] - matrixRight.m[11]; + + m.m[12] = matrixLeft.m[12] - matrixRight.m[12]; + m.m[13] = matrixLeft.m[13] - matrixRight.m[13]; + m.m[14] = matrixLeft.m[14] - matrixRight.m[14]; + m.m[15] = matrixLeft.m[15] - matrixRight.m[15]; + + return m; +#endif +} + +static __inline__ GLKMatrix4 GLKMatrix4Translate(GLKMatrix4 matrix, float tx, float ty, float tz) +{ + GLKMatrix4 m = { matrix.m[0], matrix.m[1], matrix.m[2], matrix.m[3], + matrix.m[4], matrix.m[5], matrix.m[6], matrix.m[7], + matrix.m[8], matrix.m[9], matrix.m[10], matrix.m[11], + matrix.m[0] * tx + matrix.m[4] * ty + matrix.m[8] * tz + matrix.m[12], + matrix.m[1] * tx + matrix.m[5] * ty + matrix.m[9] * tz + matrix.m[13], + matrix.m[2] * tx + matrix.m[6] * ty + matrix.m[10] * tz + matrix.m[14], + matrix.m[15] }; + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4TranslateWithVector3(GLKMatrix4 matrix, GLKVector3 translationVector) +{ + GLKMatrix4 m = { matrix.m[0], matrix.m[1], matrix.m[2], matrix.m[3], + matrix.m[4], matrix.m[5], matrix.m[6], matrix.m[7], + matrix.m[8], matrix.m[9], matrix.m[10], matrix.m[11], + matrix.m[0] * translationVector.v[0] + matrix.m[4] * translationVector.v[1] + matrix.m[8] * translationVector.v[2] + matrix.m[12], + matrix.m[1] * translationVector.v[0] + matrix.m[5] * translationVector.v[1] + matrix.m[9] * translationVector.v[2] + matrix.m[13], + matrix.m[2] * translationVector.v[0] + matrix.m[6] * translationVector.v[1] + matrix.m[10] * translationVector.v[2] + matrix.m[14], + matrix.m[15] }; + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4TranslateWithVector4(GLKMatrix4 matrix, GLKVector4 translationVector) +{ + GLKMatrix4 m = { matrix.m[0], matrix.m[1], matrix.m[2], matrix.m[3], + matrix.m[4], matrix.m[5], matrix.m[6], matrix.m[7], + matrix.m[8], matrix.m[9], matrix.m[10], matrix.m[11], + matrix.m[0] * translationVector.v[0] + matrix.m[4] * translationVector.v[1] + matrix.m[8] * translationVector.v[2] + matrix.m[12], + matrix.m[1] * translationVector.v[0] + matrix.m[5] * translationVector.v[1] + matrix.m[9] * translationVector.v[2] + matrix.m[13], + matrix.m[2] * translationVector.v[0] + matrix.m[6] * translationVector.v[1] + matrix.m[10] * translationVector.v[2] + matrix.m[14], + matrix.m[15] }; + return m; +} + +static __inline__ GLKMatrix4 GLKMatrix4Scale(GLKMatrix4 matrix, float sx, float sy, float sz) +{ +#if defined(__ARM_NEON__) + float32x4x4_t iMatrix = *(float32x4x4_t *)&matrix; + float32x4x4_t m; + + m.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)sx); + m.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)sy); + m.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)sz); + m.val[3] = iMatrix.val[3]; + + return *(GLKMatrix4 *)&m; +#else + GLKMatrix4 m = { matrix.m[0] * sx, matrix.m[1] * sx, matrix.m[2] * sx, matrix.m[3] * sx, + matrix.m[4] * sy, matrix.m[5] * sy, matrix.m[6] * sy, matrix.m[7] * sy, + matrix.m[8] * sz, matrix.m[9] * sz, matrix.m[10] * sz, matrix.m[11] * sz, + matrix.m[12], matrix.m[13], matrix.m[14], matrix.m[15] }; + return m; +#endif +} + +static __inline__ GLKMatrix4 GLKMatrix4ScaleWithVector3(GLKMatrix4 matrix, GLKVector3 scaleVector) +{ +#if defined(__ARM_NEON__) + float32x4x4_t iMatrix = *(float32x4x4_t *)&matrix; + float32x4x4_t m; + + m.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)scaleVector.v[0]); + m.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)scaleVector.v[1]); + m.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)scaleVector.v[2]); + m.val[3] = iMatrix.val[3]; + + return *(GLKMatrix4 *)&m; +#else + GLKMatrix4 m = { matrix.m[0] * scaleVector.v[0], matrix.m[1] * scaleVector.v[0], matrix.m[2] * scaleVector.v[0], matrix.m[3] * scaleVector.v[0], + matrix.m[4] * scaleVector.v[1], matrix.m[5] * scaleVector.v[1], matrix.m[6] * scaleVector.v[1], matrix.m[7] * scaleVector.v[1], + matrix.m[8] * scaleVector.v[2], matrix.m[9] * scaleVector.v[2], matrix.m[10] * scaleVector.v[2], matrix.m[11] * scaleVector.v[2], + matrix.m[12], matrix.m[13], matrix.m[14], matrix.m[15] }; + return m; +#endif +} + +static __inline__ GLKMatrix4 GLKMatrix4ScaleWithVector4(GLKMatrix4 matrix, GLKVector4 scaleVector) +{ +#if defined(__ARM_NEON__) + float32x4x4_t iMatrix = *(float32x4x4_t *)&matrix; + float32x4x4_t m; + + m.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)scaleVector.v[0]); + m.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)scaleVector.v[1]); + m.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)scaleVector.v[2]); + m.val[3] = iMatrix.val[3]; + + return *(GLKMatrix4 *)&m; +#else + GLKMatrix4 m = { matrix.m[0] * scaleVector.v[0], matrix.m[1] * scaleVector.v[0], matrix.m[2] * scaleVector.v[0], matrix.m[3] * scaleVector.v[0], + matrix.m[4] * scaleVector.v[1], matrix.m[5] * scaleVector.v[1], matrix.m[6] * scaleVector.v[1], matrix.m[7] * scaleVector.v[1], + matrix.m[8] * scaleVector.v[2], matrix.m[9] * scaleVector.v[2], matrix.m[10] * scaleVector.v[2], matrix.m[11] * scaleVector.v[2], + matrix.m[12], matrix.m[13], matrix.m[14], matrix.m[15] }; + return m; +#endif +} + +static __inline__ GLKMatrix4 GLKMatrix4Rotate(GLKMatrix4 matrix, float radians, float x, float y, float z) +{ + GLKMatrix4 rm = GLKMatrix4MakeRotation(radians, x, y, z); + return GLKMatrix4Multiply(matrix, rm); +} + +static __inline__ GLKMatrix4 GLKMatrix4RotateWithVector3(GLKMatrix4 matrix, float radians, GLKVector3 axisVector) +{ + GLKMatrix4 rm = GLKMatrix4MakeRotation(radians, axisVector.v[0], axisVector.v[1], axisVector.v[2]); + return GLKMatrix4Multiply(matrix, rm); +} + +static __inline__ GLKMatrix4 GLKMatrix4RotateWithVector4(GLKMatrix4 matrix, float radians, GLKVector4 axisVector) +{ + GLKMatrix4 rm = GLKMatrix4MakeRotation(radians, axisVector.v[0], axisVector.v[1], axisVector.v[2]); + return GLKMatrix4Multiply(matrix, rm); +} + +static __inline__ GLKMatrix4 GLKMatrix4RotateX(GLKMatrix4 matrix, float radians) +{ + GLKMatrix4 rm = GLKMatrix4MakeXRotation(radians); + return GLKMatrix4Multiply(matrix, rm); +} + +static __inline__ GLKMatrix4 GLKMatrix4RotateY(GLKMatrix4 matrix, float radians) +{ + GLKMatrix4 rm = GLKMatrix4MakeYRotation(radians); + return GLKMatrix4Multiply(matrix, rm); +} + +static __inline__ GLKMatrix4 GLKMatrix4RotateZ(GLKMatrix4 matrix, float radians) +{ + GLKMatrix4 rm = GLKMatrix4MakeZRotation(radians); + return GLKMatrix4Multiply(matrix, rm); +} + +static __inline__ GLKVector3 GLKMatrix4MultiplyVector3(GLKMatrix4 matrixLeft, GLKVector3 vectorRight) +{ + GLKVector4 v4 = GLKMatrix4MultiplyVector4(matrixLeft, GLKVector4Make(vectorRight.v[0], vectorRight.v[1], vectorRight.v[2], 0.0f)); + return GLKVector3Make(v4.v[0], v4.v[1], v4.v[2]); +} + +static __inline__ GLKVector3 GLKMatrix4MultiplyVector3WithTranslation(GLKMatrix4 matrixLeft, GLKVector3 vectorRight) +{ + GLKVector4 v4 = GLKMatrix4MultiplyVector4(matrixLeft, GLKVector4Make(vectorRight.v[0], vectorRight.v[1], vectorRight.v[2], 1.0f)); + return GLKVector3Make(v4.v[0], v4.v[1], v4.v[2]); +} + +static __inline__ GLKVector3 GLKMatrix4MultiplyAndProjectVector3(GLKMatrix4 matrixLeft, GLKVector3 vectorRight) +{ + GLKVector4 v4 = GLKMatrix4MultiplyVector4(matrixLeft, GLKVector4Make(vectorRight.v[0], vectorRight.v[1], vectorRight.v[2], 1.0f)); + return GLKVector3MultiplyScalar(GLKVector3Make(v4.v[0], v4.v[1], v4.v[2]), 1.0f / v4.v[3]); +} + +static __inline__ void GLKMatrix4MultiplyVector3Array(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount) +{ + size_t i; + for (i=0; i < vectorCount; i++) + vectors[i] = GLKMatrix4MultiplyVector3(matrix, vectors[i]); +} + +static __inline__ void GLKMatrix4MultiplyVector3ArrayWithTranslation(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount) +{ + size_t i; + for (i=0; i < vectorCount; i++) + vectors[i] = GLKMatrix4MultiplyVector3WithTranslation(matrix, vectors[i]); +} + +static __inline__ void GLKMatrix4MultiplyAndProjectVector3Array(GLKMatrix4 matrix, GLKVector3 *vectors, size_t vectorCount) +{ + size_t i; + for (i=0; i < vectorCount; i++) + vectors[i] = GLKMatrix4MultiplyAndProjectVector3(matrix, vectors[i]); +} + +static __inline__ GLKVector4 GLKMatrix4MultiplyVector4(GLKMatrix4 matrixLeft, GLKVector4 vectorRight) +{ +#if defined(__ARM_NEON__) + float32x4x4_t iMatrix = *(float32x4x4_t *)&matrixLeft; + float32x4_t v; + + iMatrix.val[0] = vmulq_n_f32(iMatrix.val[0], (float32_t)vectorRight.v[0]); + iMatrix.val[1] = vmulq_n_f32(iMatrix.val[1], (float32_t)vectorRight.v[1]); + iMatrix.val[2] = vmulq_n_f32(iMatrix.val[2], (float32_t)vectorRight.v[2]); + iMatrix.val[3] = vmulq_n_f32(iMatrix.val[3], (float32_t)vectorRight.v[3]); + + iMatrix.val[0] = vaddq_f32(iMatrix.val[0], iMatrix.val[1]); + iMatrix.val[2] = vaddq_f32(iMatrix.val[2], iMatrix.val[3]); + + v = vaddq_f32(iMatrix.val[0], iMatrix.val[2]); + + return *(GLKVector4 *)&v; +#else + GLKVector4 v = { matrixLeft.m[0] * vectorRight.v[0] + matrixLeft.m[4] * vectorRight.v[1] + matrixLeft.m[8] * vectorRight.v[2] + matrixLeft.m[12] * vectorRight.v[3], + matrixLeft.m[1] * vectorRight.v[0] + matrixLeft.m[5] * vectorRight.v[1] + matrixLeft.m[9] * vectorRight.v[2] + matrixLeft.m[13] * vectorRight.v[3], + matrixLeft.m[2] * vectorRight.v[0] + matrixLeft.m[6] * vectorRight.v[1] + matrixLeft.m[10] * vectorRight.v[2] + matrixLeft.m[14] * vectorRight.v[3], + matrixLeft.m[3] * vectorRight.v[0] + matrixLeft.m[7] * vectorRight.v[1] + matrixLeft.m[11] * vectorRight.v[2] + matrixLeft.m[15] * vectorRight.v[3] }; + return v; +#endif +} + +static __inline__ void GLKMatrix4MultiplyVector4Array(GLKMatrix4 matrix, GLKVector4 *vectors, size_t vectorCount) +{ + size_t i; + for (i=0; i < vectorCount; i++) + vectors[i] = GLKMatrix4MultiplyVector4(matrix, vectors[i]); +} + +#ifdef __cplusplus +} +#endif + +#endif /* __GLK_MATRIX_4_H */ diff --git a/samples/C/NWMan.h b/samples/C/NWMan.h new file mode 100644 index 00000000..abcd2ddb --- /dev/null +++ b/samples/C/NWMan.h @@ -0,0 +1,99 @@ +#ifndef _NME_WMAN_H +#define _NME_WMAN_H + +// Internal window manager API + +#include "NCompat.h" + +START_HEAD + +#include "NPos.h" +#include "NUtil.h" +#include "NTypes.h" + +NTS(NWMan_event); + +NSTRUCT(NWMan, { + // Init stuff + bool (*init)(); + bool (*destroy)(); + + // Window stuff + bool (*create_window)(); + bool (*destroy_window)(); + + void (*swap_buffers)(); + + // Event stuff + bool (*next_event)(NWMan_event* event); + + // Time stuff + uint (*get_millis)(); + void (*sleep)(uint millis); + + // Info + int rshift_key; + int lshift_key; + int left_key; + int right_key; +}); + +NENUM(NWMan_event_type, { + N_WMAN_MOUSE_MOVE = 0, + N_WMAN_MOUSE_BUTTON = 1, + N_WMAN_MOUSE_WHEEL = 2, + + N_WMAN_KEYBOARD = 10, + + N_WMAN_QUIT = 20, + N_WMAN_RESIZE = 21, + N_WMAN_FOCUS = 22 +}); + +#define N_WMAN_MOUSE_LEFT 0 +#define N_WMAN_MOUSE_RIGHT 1 +#define N_WMAN_MOUSE_MIDDLE 2 + +NSTRUCT(NWMan_event, { + NWMan_event_type type; + + union { + // Mouse + + NPos2i mouse_pos; + + struct { + short id; + bool state; + } mouse_button; + + signed char mouse_wheel; // 1 if up, -1 if down + + // Keyboard + + struct { + int key; + bool state; + } keyboard; + + // Window + + bool window_quit; // Will always be true if WM_QUIT + + NPos2i window_size; + + bool window_focus; + }; +}); + +NWMan_event NWMan_event_new(NWMan_event_type type); + + +bool NWMan_init(); +bool NWMan_destroy(); + +extern NWMan N_WMan; + +END_HEAD + +#endif diff --git a/samples/C/Nightmare.h b/samples/C/Nightmare.h new file mode 100644 index 00000000..3b639c20 --- /dev/null +++ b/samples/C/Nightmare.h @@ -0,0 +1,27 @@ +#ifndef _NMEX_NIGHTMARE_H +#define _NMEX_NIGHTMARE_H + +//#define NMEX + +#include "../src/NCompat.h" + +START_HEAD + +#include "../src/NTypes.h" +#include "../src/NUtil.h" +#include "../src/NPorting.h" +#include "../src/NGlobals.h" +#include "../src/NLog.h" +#include "../src/NWMan.h" +#include "../src/NRsc.h" +#include "../src/NShader.h" +#include "../src/NSquare.h" +#include "../src/NImage.h" +#include "../src/NSprite.h" +#include "../src/NSpritesheet.h" +#include "../src/NEntity.h" +#include "../src/Game.h" + +END_HEAD + +#endif diff --git a/samples/C/bitmap.h b/samples/C/bitmap.h new file mode 100644 index 00000000..30ab99ea --- /dev/null +++ b/samples/C/bitmap.h @@ -0,0 +1,47 @@ +#pragma once + +/* Copyright © 2010 Christoph Sünderhauf + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include "generic.h" + +typedef struct { + uint32_t numbits; + /* an array large enough for numbits to fit in. Might + * (if numbits%8!=0) have some spare bits at the end + */ + uint32_t* bits; +} bitmap_t; + + +// creates a new bitmap. +// CONTENT IS RANDOM! - use bitmap_clearall() to clear the bitmap. +bitmap_t bitmap_init(uint32_t numbits); + +// returns 1 or 0 +uint8_t bitmap_get(bitmap_t bitmap, uint32_t bitnum); +// sets a bit (to 1) +void bitmap_set(bitmap_t bitmap, uint32_t bitnum); +// clears a bit (to 0) +void bitmap_clear(bitmap_t bitmap, uint32_t bitnum); + +// clears every bit to 0 +void bitmap_clearAll(bitmap_t bitmap); + +// finds the first bit set to 0 returns 0 if no cleared bit found (0 is also returned if the first bit is cleared) +uint32_t bitmap_findFirstClear(bitmap_t bitmap); diff --git a/samples/C/color.h b/samples/C/color.h new file mode 100644 index 00000000..5c60b480 --- /dev/null +++ b/samples/C/color.h @@ -0,0 +1,44 @@ +#pragma once + +/* Copyright © 2011 Fritz Grimpen + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include + +typedef struct { + uint32_t background; + uint32_t foreground; +} console_color_t; + +#define CONSOLE_COLOR_BLACK 0x0 +#define CONSOLE_COLOR_BLUE 0x1 +#define CONSOLE_COLOR_GREEN 0x2 +#define CONSOLE_COLOR_CYAN 0x3 +#define CONSOLE_COLOR_RED 0x4 +#define CONSOLE_COLOR_MAGENTA 0x5 +#define CONSOLE_COLOR_BROWN 0x6 +#define CONSOLE_COLOR_LGREY 0x7 +#define CONSOLE_COLOR_DGREY 0x8 +#define CONSOLE_COLOR_LBLUE 0x9 +#define CONSOLE_COLOR_LGREEN 0xa +#define CONSOLE_COLOR_LCYAN 0xb +#define CONSOLE_COLOR_LRED 0xc +#define CONSOLE_COLOR_LMAGENTA 0xd +#define CONSOLE_COLOR_YELLOW 0xe +#define CONSOLE_COLOR_WHITE 0xf + diff --git a/samples/C/driver.h b/samples/C/driver.h new file mode 100644 index 00000000..e376c97d --- /dev/null +++ b/samples/C/driver.h @@ -0,0 +1,52 @@ +#pragma once + +/* Copyright © 2011 Fritz Grimpen + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include +#include + +#define CONSOLE_DRV_CAP_CLEAR 0x01 +#define CONSOLE_DRV_CAP_SCROLL 0x02 +#define CONSOLE_DRV_CAP_SET_CURSOR 0x04 + +// Input modifier keys +typedef struct { + bool shift_left:1; + bool shift_right:1; + bool control_left:1; + bool control_right:1; + bool alt:1; + bool super:1; +} console_modifiers_t; + +typedef struct { + char character; + console_modifiers_t* modifiers; +} console_read_t; + +typedef struct { + int (*write)(console_info_t*, char); + console_read_t* (*read)(console_info_t*); + + int capabilities; + + int (*_clear)(console_info_t*); + int (*scroll)(console_info_t*, int32_t); + void (*setCursor)(console_info_t*, uint32_t, uint32_t); +} console_driver_t; diff --git a/samples/C/elf.h b/samples/C/elf.h new file mode 100644 index 00000000..a270eb14 --- /dev/null +++ b/samples/C/elf.h @@ -0,0 +1,70 @@ +#pragma once + +/* Copyright © 2011 Lukas Martini + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include +#include + +#define ELF_TYPE_NONE 0 +#define ELF_TYPE_REL 1 +#define ELF_TYPE_EXEC 2 +#define ELF_TYPE_DYN 3 +#define ELF_TYPE_CORE 4 + +#define ELF_ARCH_NONE 0 +#define ELF_ARCH_386 3 + +#define ELF_VERSION_CURRENT 1 + +typedef struct { + unsigned char magic[4]; + /* Note: There _is_ other stuff in here, but we don't need it */ + unsigned char pad[12]; +} __attribute__((packed)) elf_ident_t; + +typedef struct { + uint32_t type; + uint32_t offset; + void* virtaddr; + void* physaddr; + uint32_t filesize; + uint32_t memsize; + uint32_t flags; + uint32_t alignment; +} __attribute__((packed)) elf_program_t; + +typedef struct { + elf_ident_t ident; + uint16_t type; /* Object file type */ + uint16_t machine; /* Architecture */ + uint32_t version; /* Object file version */ + void* entry; /* Entry point virtual address */ + uint32_t phoff; /* Program header table file offset */ + uint32_t shoff; /* Section header table file offset */ + uint32_t flags; /* Processor-specific flags */ + uint16_t ehsize; /* ELF header size in bytes */ + uint16_t phentsize; /* Program header table entry size */ + uint16_t phnum; /* Program header table entry count */ + uint16_t shentsize; /* Section header table entry size */ + uint16_t shnum; /* Section header table entry count */ + uint16_t shstrndx; /* Section header string table index */ +} __attribute__((packed)) elf_t; + +task_t* elf_load(elf_t* bin, char* name, char** environ, char** argv, int argc); +task_t* elf_load_file(char* path, char** environ, char** argv, int argc); diff --git a/samples/Zephir/filenames/exception.zep.c b/samples/C/exception.zep.c similarity index 100% rename from samples/Zephir/filenames/exception.zep.c rename to samples/C/exception.zep.c diff --git a/samples/Zephir/filenames/exception.zep.h b/samples/C/exception.zep.h similarity index 100% rename from samples/Zephir/filenames/exception.zep.h rename to samples/C/exception.zep.h diff --git a/samples/C/filter.h b/samples/C/filter.h new file mode 100644 index 00000000..a1a13c9f --- /dev/null +++ b/samples/C/filter.h @@ -0,0 +1,45 @@ +#pragma once + +/* Copyright © 2011 Fritz Grimpen + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include +#include +#include + +struct console_filter { + // General callback for all actions etc. + // Preferred prototype: + // char (char c, console_info_t *info, console_driver_t *input, console_driver_t *output); + char (*callback)(char, console_info_t*, console_driver_t*, console_driver_t*); + + // Specific callbacks for read and write + // Preferred prototype: + // char (char c, console_info_t *info, console_driver_t *input); + char (*read_callback)(char, console_info_t*, console_driver_t*); + + // Preferred prototype: + // char (char c, console_info_t *info, console_driver_t *output); + char (*write_callback)(char, console_info_t*, console_driver_t*); + + // The next filter in the filter chain + struct console_filter* next; +}; + +typedef struct console_filter console_filter_t; + diff --git a/samples/C/info.h b/samples/C/info.h new file mode 100644 index 00000000..50be7b69 --- /dev/null +++ b/samples/C/info.h @@ -0,0 +1,44 @@ +#pragma once + +/* Copyright © 2011 Fritz Grimpen + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include +#include + +typedef struct { + uint32_t cursor_x; + uint32_t cursor_y; + + uint32_t rows; + uint32_t columns; + + uint32_t tabstop; + + console_color_t default_color; + console_color_t current_color; + + uint8_t nonblocking; + uint8_t reverse_video; + uint8_t bold; + uint8_t blink; + uint8_t underline; + uint8_t newline_mode; + uint8_t auto_echo; + uint8_t handle_backspace; +} console_info_t; diff --git a/samples/C/interface.h b/samples/C/interface.h new file mode 100644 index 00000000..2c3bfeff --- /dev/null +++ b/samples/C/interface.h @@ -0,0 +1,47 @@ +#pragma once + +/* Copyright © 2011 Fritz Grimpen + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include +#include +#include +#include + +typedef struct { + console_info_t info; + + console_filter_t* input_filter; + console_filter_t* output_filter; + + console_driver_t* input_driver; + console_driver_t* output_driver; +} console_t; + +console_t* default_console; + +// Generate raw console, connected to the Display, Keyboard and the +// ECMA-48-Filter +void console_init(); + +size_t console_write(console_t* console, const char* buffer, int32_t length); +#define console_write2(console, buffer) console_write(console, buffer, strlen(buffer)) +size_t console_read(console_t* console, char* buffer, size_t length); +size_t console_scroll(console_t* console, int32_t pages); + +void console_clear(console_t* console); diff --git a/samples/C/ip4.h b/samples/C/ip4.h new file mode 100644 index 00000000..b2c8a2a8 --- /dev/null +++ b/samples/C/ip4.h @@ -0,0 +1,50 @@ +#pragma once + +/* Copyright © 2011 Lukas Martini + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include +#include + +#define IP4_TOS_ICMP 0 + +typedef uint32_t ip4_addr_t; + +typedef struct { + unsigned int hl:4; /* both fields are 4 bits */ + unsigned int version:4; + uint8_t tos; + uint16_t len; + uint16_t id; + uint16_t off; + uint8_t ttl; + uint8_t p; + uint16_t checksum; + ip4_addr_t src; + ip4_addr_t dst; +} ip4_header_t; + +typedef struct { + uint8_t type; + uint8_t code; + uint16_t checksum; + uint16_t id; + uint16_t sequence; +} ip4_icmp_header_t; + +void ip4_receive(net_device_t* origin, net_l2proto_t proto, size_t size, void* raw); diff --git a/samples/C/multiboot.h b/samples/C/multiboot.h new file mode 100644 index 00000000..fcbc13e1 --- /dev/null +++ b/samples/C/multiboot.h @@ -0,0 +1,110 @@ +#pragma once + +/* Copyright © 2010, 2011 Lukas Martini + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include + +#define MULTIBOOT_KERNELMAGIC 0x2BADB002 + +#define MULTIBOOT_FLAG_MEM 0x001 +#define MULTIBOOT_FLAG_DEVICE 0x002 +#define MULTIBOOT_FLAG_CMDLINE 0x004 +#define MULTIBOOT_FLAG_MODS 0x008 +#define MULTIBOOT_FLAG_AOUT 0x010 +#define MULTIBOOT_FLAG_ELF 0x020 +#define MULTIBOOT_FLAG_MMAP 0x040 +#define MULTIBOOT_FLAG_CONFIG 0x080 +#define MULTIBOOT_FLAG_LOADER 0x100 +#define MULTIBOOT_FLAG_APM 0x200 +#define MULTIBOOT_FLAG_VBE 0x400 + +// The symbol table for a.out. +typedef struct +{ + uint32_t tabSize; + uint32_t strSize; + uint32_t addr; + uint32_t reserved; +} __attribute__((packed)) multiboot_aoutSymbolTable_t; + +// The section header table for ELF. +typedef struct +{ + uint32_t num; + uint32_t size; + uint32_t addr; + uint32_t shndx; +} __attribute__((packed)) multiboot_elfSectionHeaderTable_t; + +typedef struct +{ + uint32_t size; + uint64_t addr; + uint64_t length; + uint32_t type; +} __attribute__((packed)) multiboot_memoryMap_t; + +typedef struct +{ + uint32_t start; + uint32_t end; + char* cmdLine; + uint32_t reserved; +} __attribute__((packed)) multiboot_module_t; + +typedef struct +{ + uint32_t flags; + uint32_t memLower; + uint32_t memUpper; + uint32_t bootDevice; + char* cmdLine; + uint32_t modsCount; + multiboot_module_t* modsAddr; + + union + { + multiboot_aoutSymbolTable_t aoutSym; + multiboot_elfSectionHeaderTable_t elfSec; + } u; + + uint32_t mmapLength; + uint32_t mmapAddr; + + uint32_t drivesLength; + uint32_t drivesAddr; + + // ROM configuration table + uint32_t configTable; + + char* bootLoaderName; + uint32_t apmTable; + + // Video + uint32_t vbeControlInfo; + uint32_t vbeModeInfo; + uint16_t vbeMode; + uint16_t vbeInterfaceSeg; + uint16_t vbeInterfaceOff; + uint16_t vbeInterfaceLen; +} __attribute__((packed)) multiboot_info_t; + +multiboot_info_t* multiboot_info; + +void arch_multiboot_printInfo(); diff --git a/samples/C/ntru_encrypt.h b/samples/C/ntru_encrypt.h new file mode 100644 index 00000000..4893f6f9 --- /dev/null +++ b/samples/C/ntru_encrypt.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 FH Bielefeld + * + * This file is part of a FH Bielefeld project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/** + * @file ntru_encrypt.h + * Header for the internal API of ntru_encrypt.c. + * @brief header for encrypt.c + */ + +#ifndef PQC_ENCRYPT_H +#define PQC_ENCRYPT_H + + +#include "ntru_params.h" +#include "ntru_poly.h" +#include "ntru_string.h" + +#include +#include + + +/** + * encrypt the msg, using the math: + * e = (h ∗ r) + m (mod q) + * + * e = the encrypted poly + * + * h = the public key + * + * r = the random poly + * + * m = the message poly + * + * q = large mod + * + * @param msg_tern the message to encrypt, in ternary format + * @param pub_key the public key + * @param rnd the random poly (should have relatively small + * coefficients, but not restricted to {-1, 0, 1}) + * @param out the output poly which is in the range {0, q-1} + * (not ternary!) [out] + * @param params ntru_params the ntru context + */ +void +ntru_encrypt_poly( + const fmpz_poly_t msg_tern, + const fmpz_poly_t pub_key, + const fmpz_poly_t rnd, + fmpz_poly_t out, + const ntru_params *params); + +/** + * Encrypt a message in the form of a null-terminated char array and + * return a string. + * + * @param msg the message + * @param pub_key the public key + * @param rnd the random poly (should have relatively small + * coefficients, but not restricted to {-1, 0, 1}) + * @param params ntru_params the ntru context + * @return the newly allocated encrypted string + */ +string * +ntru_encrypt_string( + const string *msg, + const fmpz_poly_t pub_key, + const fmpz_poly_t rnd, + const ntru_params *params); + + +#endif /* PQC_ENCRYPT_H */ diff --git a/samples/C/portio.h b/samples/C/portio.h new file mode 100644 index 00000000..8a805680 --- /dev/null +++ b/samples/C/portio.h @@ -0,0 +1,43 @@ +#pragma once + +/* Copyright © 2011 Lukas Martini + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include +#include + +// Legacy +#define outb(args...) portio_out8(args) +#define outw(args...) portio_out16(args) +#define outl(args...) portio_out32(args) +#define outq(args...) portio_out64(args) + +#define inb(args...) portio_in8(args) +#define inw(args...) portio_in16(args) +#define inl(args...) portio_in32(args) +#define inq(args...) portio_in64(args) + +void portio_out8(uint16_t port, uint8_t value); +void portio_out16(uint16_t port, uint16_t value); +void portio_out32(uint16_t port, uint32_t value); +void portio_out64(uint16_t port, uint64_t value); + +uint8_t portio_in8(uint16_t port); +uint16_t portio_in16(uint16_t port); +uint32_t portio_in32(uint16_t port); +uint64_t portio_in64(uint16_t port); diff --git a/samples/C/scheduler.h b/samples/C/scheduler.h new file mode 100644 index 00000000..a886003c --- /dev/null +++ b/samples/C/scheduler.h @@ -0,0 +1,69 @@ +#pragma once + +/* Copyright © 2011 Lukas Martini + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include +#include +#include + +#define SCHEDULER_MAXNAME 256 +#define SCHEDULER_TASK_PATH_MAX 256 + +// Single linked list +typedef struct task { + uint32_t pid; + char name[SCHEDULER_MAXNAME]; + struct task *parent; + cpu_state_t* state; + struct task* next; + struct task* previous; + + void* stack; + void* entry; + struct vmem_context *memory_context; + + // Current task state + enum { + TASK_STATE_KILLED, + TASK_STATE_TERMINATED, + TASK_STATE_BLOCKING, + TASK_STATE_STOPPED, + TASK_STATE_RUNNING + } task_state; + + char** environ; + char** argv; + int argc; + + // TODO Is this actually the same as PATH_MAX in our toolchain? + char cwd[SCHEDULER_TASK_PATH_MAX + 1]; +} task_t; + +int scheduler_state; + +task_t* scheduler_new(void* entry, task_t* parent, char name[SCHEDULER_MAXNAME], + char** environ, char** argv, int argc, struct vmem_context* memory_context, bool map_structs); +void scheduler_add(task_t *task); +void scheduler_terminate_current(); +task_t* scheduler_get_current(); +task_t* scheduler_select(cpu_state_t* lastRegs); +void scheduler_init(); +void scheduler_yield(); +void scheduler_remove(task_t *t); +task_t* scheduler_fork(task_t* to_fork, cpu_state_t* state); \ No newline at end of file diff --git a/samples/C/syscalls.h b/samples/C/syscalls.h new file mode 100644 index 00000000..dc054e2b --- /dev/null +++ b/samples/C/syscalls.h @@ -0,0 +1,95 @@ +#pragma once + +/* Copyright © 2011 Fritz Grimpen + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include +#include + +#include "syscalls/write.h" +#include "syscalls/exit.h" +#include "syscalls/getpid.h" +#include "syscalls/getppid.h" +#include "syscalls/read.h" +#include "syscalls/brk.h" +#include "syscalls/mmap.h" +#include "syscalls/munmap.h" +#include "syscalls/test.h" +#include "syscalls/hostname.h" +#include "syscalls/uname.h" +#include "syscalls/open.h" +#include "syscalls/execve.h" +#include "syscalls/seek.h" +#include "syscalls/opendir.h" +#include "syscalls/readdir.h" +#include "syscalls/kill.h" +#include "syscalls/getexecdata.h" +#include "syscalls/cwd.h" +#include "syscalls/fork.h" + +syscall_t syscall_table[] = { + NULL, + sys_exit, // 1 + sys_read, // 2 + sys_write, // 3 + sys_getpid, // 4 + sys_brk, // 5 + sys_getppid, // 6 + sys_mmap, // 7 + sys_munmap, // 8 + sys_test, // 9 + sys_get_hostname, // 10 + sys_set_hostname, // 11 + sys_uname, // 12 + sys_open, // 13 + sys_execve, // 14 + sys_seek, // 15 + sys_opendir, // 16 + sys_readdir, // 17 + sys_kill, // 18 + sys_getexecdata, // 19 + sys_chdir, // 20 + sys_getcwd, // 21 + sys_fork, // 22 +}; + +char* syscall_name_table[] = { + NULL, + "exit", // 1 + "read", // 2 + "write", // 3 + "getpid", // 4 + "brk", // 5 + "getppid", // 6 + "mmap", // 7 + "munmap", // 8 + "test", // 9 + "get_hostname", // 10 + "set_hostname", // 11 + "uname", // 12 + "open", // 13 + "execve", // 14 + "seek", // 15 + "opendir", // 16 + "readdir", // 17 + "kill", // 18 + "getexecdata", // 19 + "chdir", // 20 + "getcwd", // 21 + "fork", // 22 +}; diff --git a/samples/C/vfs.h b/samples/C/vfs.h new file mode 100644 index 00000000..3502460d --- /dev/null +++ b/samples/C/vfs.h @@ -0,0 +1,56 @@ +#pragma once + +/* Copyright © 2010, 2011 Lukas Martini + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include + +#define VFS_SEEK_SET 0 +#define VFS_SEEK_CUR 1 +#define VFS_SEEK_END 2 + +typedef struct { + uint64_t num; + char path[512]; + char mount_path[512]; + uint32_t offset; + uint32_t mountpoint; +} vfs_file_t; + +typedef struct { + uint64_t num; + char path[512]; + char mount_path[512]; + uint32_t mountpoint; +} vfs_dir_t; + +typedef void* (*vfs_read_callback_t)(char* path, uint32_t offset, uint32_t size); +typedef char* (*vfs_read_dir_callback_t)(char* path, uint32_t offset); + + +// Used to always store the last read/write attempt (used for kernel panic debugging) +char vfs_last_read_attempt[512]; + +vfs_file_t* vfs_get_from_id(uint32_t id); +vfs_dir_t* vfs_get_dir_from_id(uint32_t id); +void* vfs_read(vfs_file_t* fp, uint32_t size); +char* vfs_dir_read(vfs_dir_t* dir, uint32_t offset); +void vfs_seek(vfs_file_t* fp, uint32_t offset, int origin); +vfs_file_t* vfs_open(char* path); +vfs_dir_t* vfs_dir_open(char* path); +int vfs_mount(char* path, vfs_read_callback_t read_callback, vfs_read_dir_callback_t read_dir_callback); diff --git a/samples/C/vmem.h b/samples/C/vmem.h new file mode 100644 index 00000000..82bd29be --- /dev/null +++ b/samples/C/vmem.h @@ -0,0 +1,94 @@ +#pragma once + +/* Copyright © 2011 Fritz Grimpen + * Copyright © 2013 Lukas Martini + * + * This file is part of Xelix. + * + * Xelix is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Xelix is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Xelix. If not, see . + */ + +#include + +struct vmem_context; + +struct vmem_page +{ + enum + { + VMEM_SECTION_STACK, /* Initial stack */ + VMEM_SECTION_CODE, /* Contains program code and is read-only */ + VMEM_SECTION_DATA, /* Contains static data */ + VMEM_SECTION_HEAP, /* Allocated by brk(2) at runtime */ + VMEM_SECTION_MMAP, /* Allocated by mmap(2) at runtime */ + VMEM_SECTION_KERNEL, /* Contains kernel-internal data */ + VMEM_SECTION_UNMAPPED /* Unmapped */ + } section; + + bool readonly:1; + bool cow:1; /* Copy-on-Write mechanism */ + bool allocated:1; + + void *cow_src_addr; + void *virt_addr; + void *phys_addr; +}; + +typedef void (*vmem_iterator_t)(struct vmem_context *, struct vmem_page *, uint32_t); + +/* Initialize vmem_kernelContext for paging_init() */ +void vmem_init(); +struct vmem_context *vmem_kernelContext; +struct vmem_context *vmem_currentContext; +struct vmem_context *vmem_processContext; +void *vmem_faultAddress; + +/* Some callbacks for magic functions */ +void (*vmem_applyPage)(struct vmem_context *, struct vmem_page *); + +/* Generate new page context */ +struct vmem_context *vmem_new(); +struct vmem_page *vmem_new_page(); + +int vmem_add_page(struct vmem_context *ctx, struct vmem_page *pg); + +struct vmem_page *vmem_get_page_phys(struct vmem_context *ctx, void *phys_addr); +struct vmem_page *vmem_get_page_virt(struct vmem_context *ctx, void *virt_addr); +struct vmem_page *vmem_get_page(struct vmem_context *ctx, uint32_t offset); + +/* Remove pages in a specific context by physical or virtual address */ +struct vmem_page *vmem_rm_page_phys(struct vmem_context *ctx, void *phys_addr); +struct vmem_page *vmem_rm_page_virt(struct vmem_context *ctx, void *virt_addr); + +/* Iterator */ +int vmem_iterate(struct vmem_context *ctx, vmem_iterator_t callback); + +uint32_t vmem_count_pages(struct vmem_context *ctx); +void vmem_dump_page(struct vmem_page *pg); +void vmem_dump(struct vmem_context *ctx); +void vmem_handle_fault(uint32_t code, void *addr, void *instruction); + +/* Get/Set cached paging context */ +void vmem_set_cache(struct vmem_context *ctx, void *cache); +void *vmem_get_cache(struct vmem_context *ctx); + +#ifdef __i386__ + #define PAGE_SIZE 4096 + #define VMEM_ALIGN(x) (typeof(x))(((intptr_t)(x) & 0xFFFFF000) + 0x1000) + #define VMEM_ALIGN_DOWN(x) (typeof(x))( \ + ((intptr_t)(x) - ((intptr_t)(x) % PAGE_SIZE))) +#else + #define PAGE_SIZE 0 + #define VMEM_ALIGN(x) (x) +#endif diff --git a/samples/CLIPS/demo.clp b/samples/CLIPS/demo.clp new file mode 100644 index 00000000..45cb4828 --- /dev/null +++ b/samples/CLIPS/demo.clp @@ -0,0 +1,343 @@ +;;;*************************** +;;;* DEFFACTS KNOWLEDGE BASE * +;;;*************************** + +(deffacts MAIN::knowledge-base + (welcome (message WelcomeMessage)) + (goal (variable type.animal)) + (legalanswers (values yes no)) + (displayanswers (values "Yes" "No")) + (rule (if backbone is yes) + (then superphylum is backbone)) + (rule (if backbone is no) + (then superphylum is jellyback)) + (question (variable backbone) + (query backbone.query)) + (rule (if superphylum is backbone and + warm.blooded is yes) + (then phylum is warm)) + (rule (if superphylum is backbone and + warm.blooded is no) + (then phylum is cold)) + (question (variable warm.blooded) + (query warm.blooded.query)) + (rule (if superphylum is jellyback and + live.prime.in.soil is yes) + (then phylum is soil)) + (rule (if superphylum is jellyback and + live.prime.in.soil is no) + (then phylum is elsewhere)) + (question (variable live.prime.in.soil) + (query live.prime.in.soil.query)) + (rule (if phylum is warm and + has.breasts is yes) + (then class is breasts)) + (rule (if phylum is warm and + has.breasts is no) + (then type.animal is bird)) + (question (variable has.breasts) + (query has.breasts.query)) + (rule (if phylum is cold and + always.in.water is yes) + (then class is water)) + (rule (if phylum is cold and + always.in.water is no) + (then class is dry)) + (question (variable always.in.water) + (query always.in.water.query)) + (rule (if phylum is soil and + flat.bodied is yes) + (then type.animal is flatworm)) + (rule (if phylum is soil and + flat.bodied is no) + (then type.animal is worm.leech)) + (question (variable flat.bodied) + (query flat.bodied.query)) + (rule (if phylum is elsewhere and + body.in.segments is yes) + (then class is segments)) + (rule (if phylum is elsewhere and + body.in.segments is no) + (then class is unified)) + (question (variable body.in.segments) + (query body.in.segments.query)) + (rule (if class is breasts and + can.eat.meat is yes) + (then order is meat)) + (rule (if class is breasts and + can.eat.meat is no) + (then order is vegy)) + (question (variable can.eat.meat) + (query can.eat.meat.query)) + (rule (if class is water and + boney is yes) + (then type.animal is fish)) + (rule (if class is water and + boney is no) + (then type.animal is shark.ray)) + (question (variable boney) + (query boney.query)) + (rule (if class is dry and + scaly is yes) + (then order is scales)) + (rule (if class is dry and + scaly is no) + (then order is soft)) + (question (variable scaly) + (query scaly.query)) + (rule (if class is segments and + shell is yes) + (then order is shell)) + (rule (if class is segments and + shell is no) + (then type.animal is centipede.millipede.insect)) + (question (variable shell) + (query shell.query)) + (rule (if class is unified and + digest.cells is yes) + (then order is cells)) + (rule (if class is unified and + digest.cells is no) + (then order is stomach)) + (question (variable digest.cells) + (query digest.cells.query)) + (rule (if order is meat and + fly is yes) + (then type.animal is bat)) + (rule (if order is meat and + fly is no) + (then family is nowings)) + (question (variable fly) + (query fly.query)) + (rule (if order is vegy and + hooves is yes) + (then family is hooves)) + (rule (if order is vegy and + hooves is no) + (then family is feet)) + (question (variable hooves) + (query hooves.query)) + (rule (if order is scales and + rounded.shell is yes) + (then type.animal is turtle)) + (rule (if order is scales and + rounded.shell is no) + (then family is noshell)) + (question (variable rounded.shell) + (query rounded.shell.query)) + (rule (if order is soft and + jump is yes) + (then type.animal is frog)) + (rule (if order is soft and + jump is no) + (then type.animal is salamander)) + (question (variable jump) + (query jump.query)) + (rule (if order is shell and + tail is yes) + (then type.animal is lobster)) + (rule (if order is shell and + tail is no) + (then type.animal is crab)) + (question (variable tail) + (query tail.query)) + (rule (if order is cells and + stationary is yes) + (then family is stationary)) + (rule (if order is cells and + stationary is no) + (then type.animal is jellyfish)) + (question (variable stationary) + (query stationary.query)) + (rule (if order is stomach and + multicelled is yes) + (then family is multicelled)) + (rule (if order is stomach and + multicelled is no) + (then type.animal is protozoa)) + (question (variable multicelled) + (query multicelled.query)) + (rule (if family is nowings and + opposing.thumb is yes) + (then genus is thumb)) + (rule (if family is nowings and + opposing.thumb is no) + (then genus is nothumb)) + (question (variable opposing.thumb) + (query opposing.thumb.query)) + (rule (if family is hooves and + two.toes is yes) + (then genus is twotoes)) + (rule (if family is hooves and + two.toes is no) + (then genus is onetoe)) + (question (variable two.toes) + (query two.toes.query)) + (rule (if family is feet and + live.in.water is yes) + (then genus is water)) + (rule (if family is feet and + live.in.water is no) + (then genus is dry)) + (question (variable live.in.water) + (query live.in.water.query)) + (rule (if family is noshell and + limbs is yes) + (then type.animal is crocodile.alligator)) + (rule (if family is noshell and + limbs is no) + (then type.animal is snake)) + (question (variable limbs) + (query limbs.query)) + (rule (if family is stationary and + spikes is yes) + (then type.animal is sea.anemone)) + (rule (if family is stationary and + spikes is no) + (then type.animal is coral.sponge)) + (question (variable spikes) + (query spikes.query)) + (rule (if family is multicelled and + spiral.shell is yes) + (then type.animal is snail)) + (rule (if family is multicelled and + spiral.shell is no) + (then genus is noshell)) + (question (variable spiral.shell) + (query spiral.shell.query)) + (rule (if genus is thumb and + prehensile.tail is yes) + (then type.animal is monkey)) + (rule (if genus is thumb and + prehensile.tail is no) + (then species is notail)) + (question (variable prehensile.tail) + (query prehensile.tail.query)) + (rule (if genus is nothumb and + over.400 is yes) + (then species is 400)) + (rule (if genus is nothumb and + over.400 is no) + (then species is under400)) + (question (variable over.400) + (query over.400.query)) + (rule (if genus is twotoes and + horns is yes) + (then species is horns)) + (rule (if genus is twotoes and + horns is no) + (then species is nohorns)) + (question (variable horns) + (query horns.query)) + (rule (if genus is onetoe and + plating is yes) + (then type.animal is rhinoceros)) + (rule (if genus is onetoe and + plating is no) + (then type.animal is horse.zebra)) + (question (variable plating) + (query plating.query)) + (rule (if genus is water and + hunted is yes) + (then type.animal is whale)) + (rule (if genus is water and + hunted is no) + (then type.animal is dolphin.porpoise)) + (question (variable hunted) + (query hunted.query)) + (rule (if genus is dry and + front.teeth is yes) + (then species is teeth)) + (rule (if genus is dry and + front.teeth is no) + (then species is noteeth)) + (question (variable front.teeth) + (query front.teeth.query)) + (rule (if genus is noshell and + bivalve is yes) + (then type.animal is clam.oyster)) + (rule (if genus is noshell and + bivalve is no) + (then type.animal is squid.octopus)) + (question (variable bivalve) + (query bivalve.query)) + (rule (if species is notail and + nearly.hairless is yes) + (then type.animal is man)) + (rule (if species is notail and + nearly.hairless is no) + (then subspecies is hair)) + (question (variable nearly.hairless) + (query nearly.hairless.query)) + (rule (if species is 400 and + land.based is yes) + (then type.animal is bear.tiger.lion)) + (rule (if species is 400 and + land.based is no) + (then type.animal is walrus)) + (question (variable land.based) + (query land.based.query)) + (rule (if species is under400 and + thintail is yes) + (then type.animal is cat)) + (rule (if species is under400 and + thintail is no) + (then type.animal is coyote.wolf.fox.dog)) + (question (variable thintail) + (query thintail.query)) + (rule (if species is nohorns and + lives.in.desert is yes) + (then type.animal is camel)) + (rule (if species is nohorns and + lives.in.desert is no and + semi.aquatic is no) + (then type.animal is giraffe)) + (rule (if species is nohorns and + lives.in.desert is no and + semi.aquatic is yes) + (then type.animal is hippopotamus)) + (question (variable lives.in.desert) + (query lives.in.desert.query)) + (question (variable semi.aquatic) + (query semi.aquatic.query)) + (rule (if species is teeth and + large.ears is yes) + (then type.animal is rabbit)) + (rule (if species is teeth and + large.ears is no) + (then type.animal is rat.mouse.squirrel.beaver.porcupine)) + (question (variable large.ears) + (query large.ears.query)) + (rule (if species is noteeth and + pouch is yes) + (then type.animal is kangaroo.koala.bear)) + (rule (if species is noteeth and + pouch is no) + (then type.animal is mole.shrew.elephant)) + (question (variable pouch) + (query pouch.query)) + (rule (if subspecies is hair and + long.powerful.arms is yes) + (then type.animal is orangutan.gorilla.chimpanzee)) + (rule (if subspecies is hair and + long.powerful.arms is no) + (then type.animal is baboon)) + (question (variable long.powerful.arms) + (query long.powerful.arms.query)) + (rule (if species is horns and + fleece is yes) + (then type.animal is sheep.goat)) + (rule (if species is horns and + fleece is no) + (then subsubspecies is nofleece)) + (question (variable fleece) + (query fleece.query)) + (rule (if subsubspecies is nofleece and + domesticated is yes) + (then type.animal is cow)) + (rule (if subsubspecies is nofleece and + domesticated is no) + (then type.animal is deer.moose.antelope)) + (question (variable domesticated) + (query domesticated.query)) + (answer (prefix "I think your animal is a ") (variable type.animal) (postfix "."))) diff --git a/samples/CLIPS/sudoku.clp b/samples/CLIPS/sudoku.clp new file mode 100644 index 00000000..cbdbb92d --- /dev/null +++ b/samples/CLIPS/sudoku.clp @@ -0,0 +1,281 @@ +;;; http://www.angusj.com/sudoku/hints +;;; http://www.scanraid.com/BasicStrategies.htm +;;; http://www.sudokuoftheday.com/pages/techniques-overview +;;; http://www.sudokuonline.us/sudoku_solving_techniques +;;; http://www.sadmansoftware.com/sudoku/techniques.htm +;;; http://www.krazydad.com/blog/2005/09/29/an-index-of-sudoku-strategies/ + +;;; ####################### +;;; DEFTEMPLATES & DEFFACTS +;;; ####################### + +(deftemplate possible + (slot row) + (slot column) + (slot value) + (slot group) + (slot id)) + +(deftemplate impossible + (slot id) + (slot value) + (slot priority) + (slot reason)) + +(deftemplate technique-employed + (slot reason) + (slot priority)) + +(deftemplate technique + (slot name) + (slot priority)) + +(deffacts startup + (phase grid-values)) + +(deftemplate size-value + (slot size) + (slot value)) + +(deffacts values + (size-value (size 1) (value 1)) + (size-value (size 2) (value 2)) + (size-value (size 2) (value 3)) + (size-value (size 2) (value 4)) + (size-value (size 3) (value 5)) + (size-value (size 3) (value 6)) + (size-value (size 3) (value 7)) + (size-value (size 3) (value 8)) + (size-value (size 3) (value 9)) + (size-value (size 4) (value 10)) + (size-value (size 4) (value 11)) + (size-value (size 4) (value 12)) + (size-value (size 4) (value 13)) + (size-value (size 4) (value 14)) + (size-value (size 4) (value 15)) + (size-value (size 4) (value 16)) + (size-value (size 5) (value 17)) + (size-value (size 5) (value 18)) + (size-value (size 5) (value 19)) + (size-value (size 5) (value 20)) + (size-value (size 5) (value 21)) + (size-value (size 5) (value 22)) + (size-value (size 5) (value 23)) + (size-value (size 5) (value 24)) + (size-value (size 5) (value 25))) + +;;; ########### +;;; SETUP RULES +;;; ########### + +;;; *********** +;;; stress-test +;;; *********** + +(defrule stress-test + + (declare (salience 10)) + + (phase match) + + (stress-test) + + (priority ?last) + + (not (priority ?p&:(> ?p ?last))) + + (technique (priority ?next&:(> ?next ?last))) + + (not (technique (priority ?p&:(> ?p ?last)&:(< ?p ?next)))) + + => + + (assert (priority ?next))) + +;;; ***************** +;;; enable-techniques +;;; ***************** + +(defrule enable-techniques + + (declare (salience 10)) + + (phase match) + + (size ?) + + (not (possible (value any))) + + => + + (assert (priority 1))) + +;;; ********** +;;; expand-any +;;; ********** + +(defrule expand-any + + (declare (salience 10)) + + (phase expand-any) + + ?f <- (possible (row ?r) (column ?c) (value any) (group ?g) (id ?id)) + + (not (possible (value any) (id ?id2&:(< ?id2 ?id)))) + + (size ?s) + + (size-value (size ?as&:(<= ?as ?s)) (value ?v)) + + (not (possible (row ?r) (column ?c) (value ?v))) + + (not (and (size-value (value ?v2&:(< ?v2 ?v))) + + (not (possible (row ?r) (column ?c) (value ?v2))))) + + => + + (assert (possible (row ?r) (column ?c) (value ?v) (group ?g) (id ?id)))) + +;;; ***************** +;;; position-expanded +;;; ***************** + +(defrule position-expanded + + (declare (salience 10)) + + (phase expand-any) + + ?f <- (possible (row ?r) (column ?c) (value any) (group ?g) (id ?id)) + + (size ?s) + + (not (and (size-value (size ?as&:(<= ?as ?s)) (value ?v)) + + (not (possible (row ?r) (column ?c) (value ?v))))) + + => + + (retract ?f)) + +;;; ########### +;;; PHASE RULES +;;; ########### + +;;; *************** +;;; expand-any-done +;;; *************** + +(defrule expand-any-done + + (declare (salience 10)) + + ?f <- (phase expand-any) + + (not (possible (value any))) + + => + + (retract ?f) + + (assert (phase initial-output)) + (assert (print-position 1 1))) + +;;; *********** +;;; begin-match +;;; *********** + +(defrule begin-match + + (declare (salience -20)) + + ?f <- (phase initial-output) + + => + + (retract ?f) + + (assert (phase match))) + +;;; ***************** +;;; begin-elimination +;;; ***************** + +(defrule begin-elimination + + (declare (salience -20)) + + ?f <- (phase match) + + (not (not (impossible))) + + => + + (retract ?f) + + (assert (phase elimination))) + +;;; ************* +;;; next-priority +;;; ************* + +(defrule next-priority + + (declare (salience -20)) + + (phase match) + + (not (impossible)) + + (priority ?last) + + (not (priority ?p&:(> ?p ?last))) + + (technique (priority ?next&:(> ?next ?last))) + + (not (technique (priority ?p&:(> ?p ?last)&:(< ?p ?next)))) + + => + + (assert (priority ?next))) + +;;; ************ +;;; begin-output +;;; ************ + +(defrule begin-output + + (declare (salience -20)) + + ?f <- (phase match) + + (not (impossible)) + + (priority ?last) + + (not (priority ?p&:(> ?p ?last))) + + (not (technique (priority ?next&:(> ?next ?last)))) + + => + + (retract ?f) + + (assert (phase final-output)) + (assert (print-position 1 1))) + + + + + + + + + + + + + + diff --git a/samples/CMake/filenames/CMakeLists.txt b/samples/CMake/filenames/CMakeLists.txt new file mode 100644 index 00000000..27f3b3a7 --- /dev/null +++ b/samples/CMake/filenames/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 2.8) + +project(Foo) + +set(CMAKE_SKIP_RPATH TRUE) +set(CMAKE_INSTALL_PREFIX "/usr/local") + +add_subdirectory(bar) + +add_executable(foo foo.c) +target_link_libraries(foo pthread) +install(TARGETS foo DESTINATION bin) diff --git a/samples/CMake/sample1.cmake b/samples/CMake/sample1.cmake new file mode 100644 index 00000000..c4b23485 --- /dev/null +++ b/samples/CMake/sample1.cmake @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 2.6) + +enable_testing() + +set(CMAKE_BUILD_TYPE debug) + +include_directories("/usr/local/include") + +find_library(ssl_LIBRARY NAMES ssl PATHS "/usr/local/lib") + +add_custom_command(OUTPUT "ver.c" "ver.h" COMMAND ./ver.sh) + +add_executable(foo foo.c bar.c baz.c ver.c) + +target_link_libraries(foo ${ssl_LIBRARY}) diff --git a/samples/CMake/sample2.cmake b/samples/CMake/sample2.cmake new file mode 100644 index 00000000..7411b5d6 --- /dev/null +++ b/samples/CMake/sample2.cmake @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 2.8 FATAL_ERROR) + +project(PCLVisualizer) +target_link_libraries (PCLVisualizer ${PCL_LIBRARIES}) + +#it seems it's needed only on OS X 10.9 +find_package(GLEW REQUIRED) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/include -v") + +find_package(PCL 1.7 REQUIRED) + +include_directories(${PCL_INCLUDE_DIRS}) +link_directories(${PCL_LIBRARY_DIRS}) +add_definitions(${PCL_DEFINITIONS}) + +set(PCL_BUILD_TYPE Release) + +file(GLOB PCL_openni_viewer_SRC + "src/*.h" + "src/*.cpp" +) +add_executable(PCLVisualizer ${PCL_openni_viewer_SRC}) + +#add this line to solve probem in mac os x 10.9 +target_link_libraries(PCLVisualizer ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${PCL_VISUALIZATION_LIBRARIES} ${PCL_FEATURES_LIBRARIES}) \ No newline at end of file diff --git a/samples/CMake/sample3.cmake b/samples/CMake/sample3.cmake new file mode 100644 index 00000000..7bd9ea77 --- /dev/null +++ b/samples/CMake/sample3.cmake @@ -0,0 +1,33 @@ +# Specifications for building user and development documentation. +# +# ==================================================================== +# Copyright (c) 2009 Ian Blumel. All rights reserved. +# +# This software is licensed as described in the file LICENSE, which +# you should have received as part of this distribution. +# ==================================================================== + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +FIND_FILE( SPHINX sphinx-build.exe) + +# If we are windows call to the make.bat file, otherwise rely on the Makefile +# to handle the processing. +IF(WIN32) + SET(SPHINX_MAKE make.bat) +ELSE(WIN32) + SET(SPHINX_MAKE make) +ENDIF(WIN32) + +ADD_CUSTOM_TARGET( + doc_usr + COMMAND ${SPHINX_MAKE} html + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/usr +) + +ADD_CUSTOM_TARGET( + doc_dev + COMMAND ${SPHINX_MAKE} html + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dev +) + diff --git a/samples/CMake/sample4.cmake b/samples/CMake/sample4.cmake new file mode 100644 index 00000000..e3c123a0 --- /dev/null +++ b/samples/CMake/sample4.cmake @@ -0,0 +1,33 @@ +cmake_minimum_required (VERSION 2.6) + +set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin") + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/vala) +find_package(Vala REQUIRED) +include(ValaPrecompile) +include(ValaVersion) +ensure_vala_version("0.11.0" MINIMUM) + +project (template C) + +find_package(PkgConfig) + +pkg_check_modules(GOBJECT REQUIRED gobject-2.0) +add_definitions(${GOBJECT_CFLAGS} ${GOBJECT_CFLAGS_OTHER}) +link_libraries(${GOBJECT_LIBRARIES}) +link_directories(${GOBJECT_LIBRARY_DIRS}) + + +vala_precompile(VALA_C + src/template.vala +PACKAGES +OPTIONS + --thread +CUSTOM_VAPIS +GENERATE_VAPI +GENERATE_HEADER +DIRECTORY + gen +) + +add_executable("template" ${VALA_C}) diff --git a/samples/CMake/sample5.cmake b/samples/CMake/sample5.cmake new file mode 100644 index 00000000..f87136e7 --- /dev/null +++ b/samples/CMake/sample5.cmake @@ -0,0 +1,89 @@ +# - Check if the STDCALL function exists. +# This works for non-cdecl functions (kernel32 functions, for example) +# CHECK_STDCALL_FUNCTION_EXISTS(FUNCTION FUNCTION_DUMMY_ARGS VARIABLE) +# - macro which checks if the stdcall function exists +# FUNCTION_DECLARATION - the definition of the function ( e.g.: Sleep(500) ) +# VARIABLE - variable to store the result +# +# The following variables may be set before calling this macro to +# modify the way the check is run: +# +# CMAKE_REQUIRED_FLAGS = string of compile command line flags +# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) +# CMAKE_REQUIRED_INCLUDES = list of include directories +# CMAKE_REQUIRED_LIBRARIES = list of libraries to link +# CMAKE_EXTRA_INCLUDE_FILES = list of extra includes to check in + +MACRO(CHECK_STDCALL_FUNCTION_EXISTS FUNCTION_DECLARATION VARIABLE) + IF("${VARIABLE}" MATCHES "^${VARIABLE}$") + #get includes + SET(CHECK_STDCALL_FUNCTION_PREMAIN) + FOREACH(def ${CMAKE_EXTRA_INCLUDE_FILES}) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"${def}\"\n") + ENDFOREACH(def) + + #add some default includes + IF ( HAVE_WINDOWS_H ) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"windows.h\"\n") + ENDIF ( HAVE_WINDOWS_H ) + IF ( HAVE_UNISTD_H ) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"unistd.h\"\n") + ENDIF ( HAVE_UNISTD_H ) + IF ( HAVE_DIRECT_H ) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"direct.h\"\n") + ENDIF ( HAVE_DIRECT_H ) + IF ( HAVE_IO_H ) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"io.h\"\n") + ENDIF ( HAVE_IO_H ) + IF ( HAVE_SYS_TIMEB_H ) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"sys/timeb.h\"\n") + ENDIF ( HAVE_SYS_TIMEB_H ) + + STRING(REGEX REPLACE "(\\(.*\\))" "" CHECK_STDCALL_FUNCTION_EXISTS_FUNCTION ${FUNCTION_DECLARATION} ) + + SET(MACRO_CHECK_STDCALL_FUNCTION_DEFINITIONS "${CMAKE_REQUIRED_FLAGS}") + MESSAGE(STATUS "Looking for ${CHECK_STDCALL_FUNCTION_EXISTS_FUNCTION}") + + IF(CMAKE_REQUIRED_LIBRARIES) + SET(CHECK_STDCALL_FUNCTION_EXISTS_ADD_LIBRARIES + "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + ELSE(CMAKE_REQUIRED_LIBRARIES) + SET(CHECK_STDCALL_FUNCTION_EXISTS_ADD_LIBRARIES) + ENDIF(CMAKE_REQUIRED_LIBRARIES) + + IF(CMAKE_REQUIRED_INCLUDES) + SET(CHECK_STDCALL_FUNCTION_EXISTS_ADD_INCLUDES + "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") + ELSE(CMAKE_REQUIRED_INCLUDES) + SET(CHECK_STDCALL_FUNCTION_EXISTS_ADD_INCLUDES) + ENDIF(CMAKE_REQUIRED_INCLUDES) + + SET(CHECK_STDCALL_FUNCTION_DECLARATION ${FUNCTION_DECLARATION}) + CONFIGURE_FILE("${clucene-shared_SOURCE_DIR}/cmake/CheckStdCallFunctionExists.cpp.in" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckStdCallFunctionExists.cpp" IMMEDIATE @ONLY) + FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckStdCallFunctionExists.cpp" + CHECK_STDCALL_FUNCTION_CONTENT) + + TRY_COMPILE(${VARIABLE} + ${CMAKE_BINARY_DIR} + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckStdCallFunctionExists.cpp" + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_STDCALL_FUNCTION_DEFINITIONS} + "${CHECK_STDCALL_FUNCTION_EXISTS_ADD_LIBRARIES}" + "${CHECK_STDCALL_FUNCTION_EXISTS_ADD_INCLUDES}" + OUTPUT_VARIABLE OUTPUT) + IF(${VARIABLE}) + SET(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION_DECLARATION}") + MESSAGE(STATUS "Looking for ${FUNCTION_DECLARATION} - found") + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining if the stdcall function ${FUNCTION_DECLARATION} exists passed with the following output:\n" + "${OUTPUT}\nCheckStdCallFunctionExists.cpp:\n${CHECK_STDCALL_FUNCTION_CONTENT}\n\n") + ELSE(${VARIABLE}) + MESSAGE(STATUS "Looking for ${FUNCTION_DECLARATION} - not found") + SET(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION_DECLARATION}") + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if the stdcall function ${FUNCTION_DECLARATION} exists failed with the following output:\n" + "${OUTPUT}\nCheckStdCallFunctionExists.cpp:\n${CHECK_STDCALL_FUNCTION_CONTENT}\n\n") + ENDIF(${VARIABLE}) + ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$") +ENDMACRO(CHECK_STDCALL_FUNCTION_EXISTS) diff --git a/samples/CMake/uninstall.cmake.in b/samples/CMake/uninstall.cmake.in new file mode 100644 index 00000000..a5b7436f --- /dev/null +++ b/samples/CMake/uninstall.cmake.in @@ -0,0 +1,22 @@ +IF (NOT EXISTS "@PROJECT_BINARY_DIR@/install_manifest.txt") + MESSAGE (FATAL_ERROR "Cannot find install manifest: \"@PROJECT_BINARY_DIR@/install_manifest.txt\"") +ENDIF (NOT EXISTS "@PROJECT_BINARY_DIR@/install_manifest.txt") + +FILE (READ "@PROJECT_BINARY_DIR@/install_manifest.txt" files) +STRING (REGEX REPLACE "\n" ";" files "${files}") +FOREACH (file ${files}) + MESSAGE (STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + IF (EXISTS "$ENV{DESTDIR}${file}") + EXEC_PROGRAM ( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + IF (NOT "${rm_retval}" STREQUAL 0) + MESSAGE (FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + ENDIF (NOT "${rm_retval}" STREQUAL 0) + ELSE (EXISTS "$ENV{DESTDIR}${file}") + MESSAGE (STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + ENDIF (EXISTS "$ENV{DESTDIR}${file}") +ENDFOREACH (file) + diff --git a/samples/CartoCSS/amenity-points.mss b/samples/CartoCSS/amenity-points.mss new file mode 100644 index 00000000..a7b94ea0 --- /dev/null +++ b/samples/CartoCSS/amenity-points.mss @@ -0,0 +1,1879 @@ +@marina-text: #576ddf; // also swimming_pool +@wetland-text: darken(#017fff, 10%); /* Also for marsh */ +@mud-text: darken(#aea397, 20%); +@shop-icon: #ac39ac; +@transportation-icon: #0092da; +@transportation-text: #0066ff; +@airtransport: #8461C4; + +@landcover-font-size: 10; +@landcover-font-size-big: 12; +@landcover-font-size-bigger: 15; +@landcover-wrap-width-size: 25; +@landcover-wrap-width-size-big: 35; +@landcover-wrap-width-size-bigger: 45; +@landcover-face-name: @oblique-fonts; + +@standard-wrap-width: 30; + +.points { + [feature = 'tourism_alpine_hut'][zoom >= 13] { + point-file: url('symbols/alpinehut.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_shelter'][zoom >= 16] { + point-file: url('symbols/shelter2.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_atm'][zoom >= 17] { + point-file: url('symbols/atm2.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_bank'][zoom >= 17] { + point-file: url('symbols/bank2.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_bar'][zoom >= 17] { + point-file: url('symbols/bar.p.20.png'); + point-placement: interior; + } + + [feature = 'amenity_bicycle_rental'][zoom >= 17] { + point-file: url('symbols/rental_bicycle.p.20.png'); + point-placement: interior; + } + + [feature = 'highway_bus_stop'] { + [zoom >= 16] { + marker-file: url('symbols/square.svg'); + marker-fill: @transportation-icon; + marker-placement: interior; + marker-width: 6; + } + [zoom >= 17] { + marker-file: url('symbols/bus_stop.p.12.png'); + marker-width: 12; + } + } + + [feature = 'amenity_bus_station'][zoom >= 16] { + point-file: url('symbols/bus_station.n.16.png'); + point-placement: interior; + } + + [feature = 'highway_traffic_signals'][zoom >= 17] { + marker-file: url('symbols/traffic_light.svg'); + marker-fill: #0a0a0a; + marker-placement: interior; + } + + [feature = 'amenity_cafe'][zoom >= 17] { + point-file: url('symbols/cafe.p.16.png'); + point-placement: interior; + } + + [feature = 'tourism_camp_site'][zoom >= 16] { + point-file: url('symbols/camping.n.16.png'); + point-placement: interior; + } + + [feature = 'highway_ford'][zoom >= 16] { + point-file: url('symbols/transport_ford.p.16.png'); + point-placement: interior; + } + + [feature = 'tourism_caravan_site'][zoom >= 16] { + point-file: url('symbols/caravan_park.p.24.png'); + point-placement: interior; + } + + [feature = 'amenity_car_sharing'][zoom >= 16] { + point-file: url('symbols/car_share.p.16.png'); + point-placement: interior; + } + + [feature = 'tourism_chalet'][zoom >= 17] { + point-file: url('symbols/chalet.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_cinema'][zoom >= 16] { + point-file: url('symbols/cinema.p.24.png'); + point-placement: interior; + } + + [feature = 'amenity_fire_station'][zoom >= 16] { + point-file: url('symbols/firestation.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_fuel'][zoom >= 17] { + point-file: url('symbols/fuel.p.16.png'); + point-placement: interior; + } + + [feature = 'tourism_guest_house'][zoom >= 17] { + point-file: url('symbols/guest_house.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_hospital'][zoom >= 15] { + point-file: url('symbols/hospital.p.16.png'); + point-placement: interior; + } + + [feature = 'tourism_hostel'][zoom >= 17] { + point-file: url('symbols/hostel.p.20.png'); + point-placement: interior; + } + + [feature = 'tourism_hotel'][zoom >= 17] { + point-file: url('symbols/hotel2.p.20.png'); + point-placement: interior; + } + + [feature = 'tourism_motel'][zoom >= 17] { + point-file: url('symbols/motel.p.20.png'); + point-placement: interior; + } + + [feature = 'tourism_information'][zoom >= 17] { + point-file: url('symbols/information.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_embassy'][zoom >= 17] { + point-file: url('symbols/embassy.png'); + point-placement: interior; + } + + [feature = 'amenity_library'][zoom >= 16] { + point-file: url('symbols/library.p.20.png'); + point-placement: interior; + } + + [feature = 'amenity_courthouse'][zoom > 16] { + point-file: url('symbols/amenity_court.p.20.png'); + point-placement: interior; + } + + [feature = 'waterway_lock'], + [feature = 'lock_yes'] { + [zoom >= 15] { + marker-fill: #969494; + marker-width: 9; + marker-line-width: 0; + marker-placement: interior; + } + } + + [feature = 'man_made_mast'][zoom >= 17] { + point-file: url('symbols/communications.p.20.png'); + point-placement: interior; + } + + [feature = 'tourism_museum'][zoom >= 16] { + point-file: url('symbols/museum.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_parking'][zoom >= 16] { + marker-file: url('symbols/parking.svg'); + marker-placement: interior; + marker-clip: false; + marker-fill: @transportation-icon; + [access != ''][access != 'public'][access != 'yes'] { + marker-opacity: 0.33; + } + } + + [feature = 'amenity_pharmacy'][zoom >= 17] { + point-file: url('symbols/pharmacy.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_place_of_worship'][zoom >= 16] { + point-file: url('symbols/place_of_worship3.p.16.png'); + point-placement: interior; + [religion = 'christian'] { + point-file: url('symbols/christian3.p.14.png'); + [denomination = 'jehovahs_witness']{ + point-file: url('symbols/place_of_worship3.p.16.png'); + } + } + [religion = 'muslim'] { + point-file: url('symbols/islamic3.p.16.png'); + } + [religion = 'sikh'] { + point-file: url('symbols/sikh3.p.16.png'); + } + [religion = 'jewish'] { + point-file: url('symbols/jewish3.p.16.png'); + } + [religion = 'hindu'] { + point-file: url('symbols/hindu.png'); + } + [religion = 'buddhist'] { + point-file: url('symbols/buddhist.png'); + } + [religion = 'shinto'] { + point-file: url('symbols/shinto.png'); + } + [religion = 'taoist'] { + point-file: url('symbols/taoist.png'); + } + } + + [feature = 'amenity_police'][zoom >= 16] { + point-file: url('symbols/police.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_post_box'][zoom >= 17] { + point-file: url('symbols/post_box.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_post_office'][zoom >= 17] { + point-file: url('symbols/post_office.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_pub'][zoom >= 17] { + point-file: url('symbols/pub.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_biergarten'][zoom >= 17] { + point-file: url('symbols/biergarten.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_recycling'][zoom >= 16] { + point-file: url('symbols/recycling.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_restaurant'][zoom >= 17] { + point-file: url('symbols/restaurant.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_fast_food'][zoom >= 17] { + point-file: url('symbols/fast_food.png'); + point-placement: interior; + } + + [feature = 'amenity_telephone'][zoom >= 17] { + point-file: url('symbols/telephone.p.16.png'); + point-placement: interior; + } + + [feature = 'amenity_emergency_phone'][zoom >= 17] { + point-file: url('symbols/sosphone.png'); + point-placement: interior; + } + + [feature = 'amenity_theatre'][zoom >= 16] { + point-file: url('symbols/theatre.p.20.png'); + point-placement: interior; + } + + [feature = 'amenity_toilets'][zoom >= 17] { + point-file: url('symbols/toilets.p.20.png'); + point-placement: interior; + } + + [feature = 'amenity_drinking_water'][zoom >= 17] { + point-file: url('symbols/food_drinkingtap.p.20.png'); + point-placement: interior; + } + + [feature = 'amenity_prison'][zoom >= 17] { + point-file: url('symbols/amenity_prison.p.20.png'); + point-placement: interior; + } + + [feature = 'tourism_viewpoint'][zoom >= 16] { + point-file: url('symbols/view_point.p.16.png'); + point-placement: interior; + } + + [feature = 'man_made_water_tower'][zoom >= 17] { + point-file: url('symbols/tower_water.p.20.png'); + point-placement: interior; + } + + [feature = 'historic_memorial'][zoom >= 17] { + point-file: url('symbols/tourist_memorial.p.20.png'); + point-placement: interior; + } + + [feature = 'historic_archaeological_site'][zoom >= 16] { + point-file: url('symbols/tourist_archaeological2.glow.24.png'); + point-placement: interior; + } + + [feature = 'shop_other'][zoom >= 17] { + marker-fill: @shop-icon; + marker-width: 6; + marker-line-width: 0; + marker-placement: interior; + marker-clip: false; + } + + [feature = 'shop_supermarket'][zoom >= 16] { + marker-file: url('symbols/shop_supermarket.svg'); + marker-placement: interior; + marker-clip: false; + marker-fill: @shop-icon; + } + + [feature = 'shop_bakery'][zoom >= 17] { + marker-file: url('symbols/shop_bakery.p.16.png'); + marker-placement: interior; + marker-clip: false; + } + + [feature = 'shop_butcher'][zoom >= 17] { + marker-file: url('symbols/shop_butcher.png'); + marker-placement: interior; + marker-clip: false; + } + + [feature = 'shop_clothes'], + [feature = 'shop_fashion'] { + [zoom >= 17] { + marker-file: url('symbols/shop_clothes.svg'); + marker-placement: interior; + marker-clip: false; + marker-fill: @shop-icon; + } + } + + [feature = 'shop_convenience'][zoom >= 17] { + marker-file: url('symbols/shop_convenience.svg'); + marker-placement: interior; + marker-clip: false; + marker-fill: @shop-icon; + } + + [feature = 'shop_department_store'][zoom >= 16] { + point-file: url('symbols/department_store.p.16.png'); + point-placement: interior; + } + + [feature = 'shop_doityourself'][zoom >= 17] { + marker-file: url('symbols/shop_diy.p.16.png'); + marker-placement: interior; + marker-clip: false; + } + + [feature = 'shop_florist'][zoom >= 17] { + marker-file: url('symbols/florist.p.16.png'); + marker-placement: interior; + marker-clip: false; + } + + [feature = 'shop_hairdresser'][zoom >= 17] { + marker-file: url('symbols/shop_hairdresser.p.16.png'); + marker-placement: interior; + marker-clip: false; + } + + [feature = 'shop_car'][zoom >= 17] { + marker-file: url('symbols/shop_car.svg'); + marker-placement: interior; + marker-clip: false; + marker-fill: @shop-icon; + } + + [feature = 'shop_car_repair'][zoom >= 17] { + marker-file: url('symbols/shopping_car_repair.p.16.png'); + marker-placement: interior; + marker-clip: false; + } + + [feature = 'shop_bicycle'][zoom >= 17] { + marker-file: url('symbols/shopping_bicycle.p.16.png'); + marker-placement: interior; + marker-clip: false; + } + + [feature = 'leisure_playground'][zoom >= 17] { + point-file: url('symbols/playground.p.20.png'); + point-placement: interior; + } + + [feature = 'tourism_picnic_site'][zoom >= 16] { + point-file: url('symbols/picnic.p.16.png'); + point-placement: interior; + } + + [feature = 'leisure_picnic_table'][zoom >= 17] { + point-file: url('symbols/picnic.p.16.png'); + point-placement: interior; + } + + [feature = 'leisure_slipway'][zoom >= 17] { + point-file: url('symbols/transport_slipway.p.20.png'); + point-placement: interior; + } + + [feature = 'aeroway_helipad'][zoom >= 16]::aeroway { + marker-file: url('symbols/helipad.svg'); + marker-clip: false; + marker-fill: @airtransport; + } + + [feature = 'aeroway_aerodrome'][zoom >= 10][zoom < 14]::aeroway { + marker-file: url('symbols/aerodrome.svg'); + marker-clip: false; + marker-fill: @airtransport; + } + + [feature = 'man_made_lighthouse'][zoom >= 15]::man_made { + point-file: url('symbols/lighthouse.p.20.png'); + point-placement: interior; + } + + [feature = 'natural_peak'][zoom >= 11]::natural { + marker-file: url('symbols/peak.svg'); + marker-fill: #d08f55; + marker-placement: interior; + } + + [feature = 'natural_volcano'][zoom >= 11]::natural { + marker-file: url('symbols/peak.svg'); + marker-fill: #d40000; + marker-placement: interior; + } + + [feature = 'natural_saddle'][zoom >= 15]::natural { + marker-file: url('symbols/saddle.svg'); + marker-fill: #d08f55; + marker-placement: interior; + } + + [feature = 'natural_cave_entrance'][zoom >= 15]::natural { + point-file: url('symbols/poi_cave.p.16.png'); + point-placement: interior; + } + + [feature = 'natural_spring'][zoom >= 14]::natural { + marker-file: url('symbols/spring.svg'); + marker-placement: interior; + } + + [feature = 'natural_tree'][zoom >= 16]::natural { + marker-placement: interior; + marker-ignore-placement: true; + marker-line-width: 0; + marker-width: 3; + marker-fill: #239c45; + [zoom >= 17] { + marker-line-width: 1; + marker-line-color: #8ef2ab; + marker-width: 4; + } + } + + [feature = 'power_generator']['generator:source' = 'wind']::power, + [feature = 'power_generator'][power_source = 'wind']::power { + [zoom >= 15] { + point-file: url('symbols/power_wind.png'); + point-placement: interior; + } + } + + [feature = 'man_made_windmill'][zoom >= 16]::man_made { + point-file: url('symbols/windmill.png'); + point-placement: interior; + } + + [feature = 'man_made_mast'][zoom >= 17]::man_made { + point-file: url('symbols/communications.p.20.png'); + point-placement: interior; + } +} + +.amenity-low-priority { + [railway = 'level_crossing'][zoom >= 14]::railway { + point-file: url('symbols/level_crossing.svg'); + point-placement: interior; + [zoom >= 16] { + point-file: url('symbols/level_crossing2.svg'); + } + } + + [highway = 'mini_roundabout'][zoom >= 16]::highway { + marker-file: url('symbols/mini_roundabout.svg'); + marker-placement: interior; + } + + [barrier = 'gate']::barrier { + [zoom >= 16] { + marker-file: url('symbols/gate.svg'); + marker-placement: interior; + } + } + + [barrier = 'lift_gate'][zoom >= 16]::barrier { + marker-file: url('symbols/liftgate.svg'); + marker-fill: #3f3f3f; + marker-placement: interior + } + + [barrier = 'bollard'], + [barrier = 'block'] { + [zoom >= 16] { + marker-width: 3; + marker-line-width: 0; + marker-fill: #7d7c7c; + marker-placement: interior; + + [zoom >= 18] { + marker-width: 4; + } + } + } +} + +.text-low-zoom[zoom < 10], +.text[zoom >= 10] { + [feature = 'place_island'][zoom >= 7][way_pixels > 3000], + [feature = 'place_island'][zoom >= 16], + [feature = 'place_islet'][zoom >= 14][way_pixels > 3000], + [feature = 'place_islet'][zoom >= 17] { + text-name: "[name]"; + text-fill: #000; + text-size: 10; + [way_pixels > 12000] { text-size: 12; } + [way_pixels > 48000] { text-size: 15; } + text-face-name: @oblique-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'amenity_pub'], + [feature = 'amenity_restaurant'], + [feature = 'amenity_cafe'], + [feature = 'amenity_fast_food'], + [feature = 'amenity_biergarten'], + [feature = 'amenity_bar'] { + [zoom >= 17] { + text-name: "[name]"; + text-fill: #734a08; + text-size: 10; + text-dy: 11; + text-face-name: @bold-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + [feature = 'amenity_bar']{ + text-dy: 13; + } + } + } + + [feature = 'amenity_library'], + [feature = 'amenity_theatre'], + [feature = 'amenity_courthouse'], + [feature = 'amenity_cinema'] { + [zoom >= 17] { + text-name: "[name]"; + text-size: 10; + text-fill: #734a08; + text-dy: 13; + text-face-name: @bold-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + [feature = 'amenity_cinema'] { + text-dy: 15; + } + } + } + + [feature = 'amenity_parking'][zoom >= 17] { + text-name: "[name]"; + text-size: 9; + text-fill: @transportation-text; + text-dy: 9; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + [access != ''][access != 'public'][access != 'yes'] { + text-fill: #66ccaf; + } + } + + [feature = 'amenity_police'][zoom >= 17] { + text-name: "[name]"; + text-size: 10; + text-fill: #734a08; + text-dy: 11; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'amenity_fire_station'][zoom >= 17] { + text-name: "[name]"; + text-size: 10; + text-fill: #734a08; + text-dy: 11; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'amenity_place_of_worship'][zoom >= 17] { + text-name: "[name]"; + text-size: 10; + text-fill: #000033; + text-dy: 12; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'natural_wood'][is_building = 'no'] { + [zoom >= 8][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@wood, 40%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'natural_peak'], + [feature = 'natural_volcano'] { + [zoom >= 13] { + text-name: "[name]"; + text-size: 10; + text-fill: brown; + text-dy: 7; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + ele/text-name: "[ele]"; + ele/text-size: 9; + ele/text-fill: brown; + ele/text-dy: 6; + ele/text-face-name: @oblique-fonts; + ele/text-halo-radius: 1; + ele/text-placement: interior; + [name != ''] { + ele/text-dy: 19; + } + } + } + + [feature = 'natural_saddle'] { + [zoom >= 15] { + text-name: "[name]"; + text-size: 10; + text-fill: brown; + text-dy: 7; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + ele/text-name: "[ele]"; + ele/text-size: 9; + ele/text-fill: brown; + ele/text-dy: 6; + ele/text-face-name: @oblique-fonts; + ele/text-halo-radius: 1; + ele/text-placement: interior; + [name != ''] { + ele/text-dy: 19; + } + } + } + + [feature = 'natural_cave_entrance'][zoom >= 15] { + text-name: "[name]"; + text-size: 10; + text-fill: brown; + text-dy: 11; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'historic_memorial'][zoom >= 17] { + text-name: "[name]"; + text-size: 9; + text-fill: brown; + text-dy: 13; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'historic_archaeological_site'][zoom >= 17] { + text-name: "[name]"; + text-size: 9; + text-fill: brown; + text-dy: 15; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'natural_water'], + [feature = 'natural_lake'], + [feature = 'landuse_reservoir'], + [feature = 'landuse_basin'] { + [way_area >= 40000000][zoom >= 10], + [way_area >= 10000000][zoom >= 11], + [way_area >= 2400000][zoom >= 12], + [way_area >= 600000][zoom >= 13], + [way_area >= 150000][zoom >= 14], + [way_area >= 80000][zoom >= 15], + [way_area >= 20000][zoom >= 16], + [zoom >= 17] { + text-name: "[name]"; + text-size: 12; + text-fill: @water-text; + text-face-name: @oblique-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + } + + [feature = 'natural_mud'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: @mud-text; + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'natural_wetland'][is_building = 'no'], + [feature = 'natural_marsh'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: @wetland-text; + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'leisure_swimming_pool'][is_building = 'no'] { + [zoom >= 14][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: @marina-text; + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'leisure_sports_centre'][is_building = 'no'], + [feature = 'leisure_stadium'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@stadium, 30%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'leisure_track'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@track, 40%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'leisure_pitch'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@pitch, 40%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'leisure_playground'] { + [way_area >= 150000][zoom >= 14], + [way_area >= 80000][zoom >= 15], + [way_area >= 20000][zoom >= 16], + [zoom >= 17] { + text-name: "[name]"; + text-size: 11; + text-dy: 13; + text-fill: darken(@park, 60%); + text-face-name: @book-fonts; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + } + + [feature = 'leisure_park'][is_building = 'no'], + [feature = 'leisure_recreation_ground'][is_building = 'no'], + [feature = 'landuse_recreation_ground'][is_building = 'no'], + [feature = 'landuse_conservation'][is_building = 'no'], + [feature = 'landuse_village_green'][is_building = 'no'], + [feature = 'leisure_common'][is_building = 'no'], + [feature = 'leisure_garden'][is_building = 'no'], + [feature = 'leisure_golf_course'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@park, 60%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'boundary_national_park'][is_building = 'no'], + [feature = 'leisure_nature_reserve'][is_building = 'no'] { + [zoom >= 8][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@park, 70%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_quarry'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@quarry, 60%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_vineyard'][is_building = 'no'], + [feature = 'landuse_orchard'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@vineyard, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1.5; /* extra halo needed to overpower the vineyard polygon pattern */ + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_cemetery'][is_building = 'no'], + [feature = 'amenity_grave_yard'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@cemetery, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1.5; /* extra halo needed to overpower the cemetery polygon pattern */ + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_residential'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@residential, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_garages'][is_building = 'no'] { + [zoom >= 13][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@garages, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_field'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@field, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_meadow'][is_building = 'no'], + [feature = 'landuse_grass'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@grass, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_allotments'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@allotments, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_forest'][is_building = 'no'] { + [zoom >= 8][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@forest, 30%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_farmyard'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@farmyard, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + [feature = 'landuse_farm'][is_building = 'no'], + [feature = 'landuse_farmland'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@farmland, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'shop_mall'], + [feature = 'landuse_retail'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@retail, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_industrial'][is_building = 'no'], + [feature = 'landuse_railway'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@industrial, 60%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_commercial'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@commercial, 60%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_brownfield'][is_building = 'no'], + [feature = 'landuse_landfill'][is_building = 'no'], + [feature = 'landuse_construction'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@construction, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'natural_bay'][zoom >= 14] { + text-name: "[name]"; + text-size: 10; + text-fill: #6699cc; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'natural_spring'][zoom >= 16] { + text-name: "[name]"; + text-size: 10; + text-fill: #6699cc; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + text-dy: 6; + } + + [feature = 'tourism_alpine_hut'][zoom >= 15] { + text-name: "[name]"; + text-size: 9; + text-fill: #6699cc; + text-dy: 11; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + [zoom >= 16] { + ele/text-name: "[ele]"; + ele/text-size: 8; + ele/text-fill: #6699cc; + ele/text-dy: 23; + ele/text-face-name: @oblique-fonts; + ele/text-halo-radius: 1; + ele/text-placement: interior; + } + } + + [feature = 'amenity_shelter'][zoom >= 17] { + text-name: "[name]"; + text-size: 9; + text-fill: #6699cc; + text-dy: 11; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + ele/text-name: "[ele]"; + ele/text-size: 8; + ele/text-fill: #6699cc; + ele/text-dy: 23; + ele/text-face-name: @oblique-fonts; + ele/text-halo-radius: 1; + ele/text-placement: interior; + } + + [feature = 'amenity_bank'][zoom >= 17] { + text-name: "[name]"; + text-size: 9; + text-fill: black; + text-dy: 12; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + text-face-name: @book-fonts; + } + + [feature = 'tourism_hotel'], + [feature = 'tourism_motel'], + [feature = 'tourism_hostel'], + [feature = 'tourism_chalet'] { + [zoom >= 17] { + text-name: "[name]"; + text-size: 10; + text-fill: #0066ff; + text-dy: 13; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + [feature = 'tourism_chalet'] { + text-dy: 11; + } + } + } + + [feature = 'amenity_embassy'][zoom >= 17] { + text-name: "[name]"; + text-size: 9; + text-fill: #0066ff; + text-dy: 9; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'tourism_guest_house'][zoom >= 17] { + text-name: "[name]"; + text-size: 8; + text-fill: #0066ff; + text-dy: 10; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'highway_bus_stop'], + [feature = 'amenity_fuel'], + [feature = 'amenity_bus_station'] { + [zoom >= 17] { + text-name: "[name]"; + text-size: 9; + text-fill: @transportation-text; + text-dy: 11; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + [feature = 'highway_bus_stop'] { + text-dy: 9; + } + } + } + + [feature = 'tourism_camp_site'][zoom >= 17] { + text-name: "[name]"; + text-size: 10; + text-fill: #0066ff; + text-dy: 15; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'tourism_caravan_site'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@campsite, 50%); + text-dy: 15; + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'waterway_lock'][zoom >= 15] { + text-name: "[name]"; + text-size: 9; + text-dy: 10; + text-fill: #0066ff; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'leisure_marina'][zoom >= 15] { + text-name: "[name]"; + text-size: 8; + text-fill: @marina-text; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + [zoom >= 17] { + text-size: 10; + } + } + + [feature = 'tourism_theme_park'][is_building = 'no'] { + [zoom >= 13][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: @theme_park; + text-face-name: @bold-fonts; /*rendered bold to improve visibility since theme parks tend to have crowded backgrounds*/ + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'tourism_museum'][zoom >= 17] { + text-name: "[name]"; + text-size: 10; + text-dy: 11; + text-fill: #734a08; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'amenity_prison'][zoom >= 17] { + text-name: "[name]"; + text-size: 10; + text-fill: #734a08; + text-dy: 16; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'tourism_attraction'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: #660033; + text-face-name: @book-fonts; + text-halo-radius: 2; + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'amenity_university'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@school, 70%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'amenity_school'][is_building = 'no'], + [feature = 'amenity_college'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@school, 70%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'amenity_kindergarten'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@school, 65%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'man_made_lighthouse'][zoom >= 15] { + text-name: "[name]"; + text-size: 9; + text-fill: #000033; + text-dy: 16; + text-face-name: @book-fonts; + text-halo-radius: 2; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'man_made_windmill'][zoom >= 17] { + text-name: "[name]"; + text-size: 9; + text-fill: #734a08; + text-dy: 12; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'amenity_hospital'][zoom >= 16] { + text-name: "[name]"; + text-fill: #da0092; + text-size: 8; + text-dy: 10; + text-face-name: @book-fonts; + text-halo-radius: 2; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'amenity_pharmacy'][zoom >= 17] { + text-name: "[name]"; + text-size: 8; + text-dy: 10; + text-fill: #da0092; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'shop_bakery'], + [feature = 'shop_clothes'], + [feature = 'shop_fashion'], + [feature = 'shop_convenience'], + [feature = 'shop_doityourself'], + [feature = 'shop_hairdresser'], + [feature = 'shop_butcher'], + [feature = 'shop_car'], + [feature = 'shop_car_repair'], + [feature = 'shop_bicycle'], + [feature = 'shop_florist'], + [feature = 'shop_other']{ + [zoom >= 17] { + text-name: "[name]"; + text-size: 10; + text-dy: 12; + text-fill: #939; + text-face-name: @book-fonts; + text-halo-radius: 1.5; + text-halo-fill: rgba(255, 255, 255, 0.8); + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + } + + [feature = 'shop_supermarket'], + [feature = 'shop_department_store'] { + [zoom >= 16] { + text-name: "[name]"; + text-size: 10; + text-dy: 12; + text-fill: #939; + text-face-name: @book-fonts; + text-halo-radius: 1.5; + text-halo-fill: rgba(255, 255, 255, 0.8); + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + } + + [feature = 'military_danger_area'][is_building = 'no'] { + [zoom >= 9][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@danger_area, 40%); + text-face-name: @bold-fonts; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'landuse_military'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@military, 40%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'aeroway_gate'][zoom >= 17] { + text-name: "[ref]"; + text-size: 10; + text-fill: #aa66cc; + text-face-name: @book-fonts; + text-halo-radius: 1; + text-wrap-width: @standard-wrap-width; + text-placement: interior; + } + + [feature = 'military_barracks'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@barracks, 40%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'tourism_zoo'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@zoo, 40%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'power_station'][is_building = 'no'][zoom >= 10], + [feature = 'power_generator'][is_building = 'no'][zoom >= 10], + [feature = 'power_sub_station'][is_building = 'no'][zoom >= 13], + [feature = 'power_substation'][is_building = 'no'][zoom >= 13]{ + [way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@power, 40%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'natural_desert'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@desert, 40%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'natural_sand'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@sand, 50%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'natural_heath'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@heath, 40%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + + [feature = 'natural_grassland'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@grassland, 60%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'natural_scrub'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@scrub, 60%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'aeroway_apron'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@apron, 60%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'natural_beach'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@beach, 60%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + text-placement: interior; + } + } + + [feature = 'highway_services'][is_building = 'no'], + [feature = 'highway_rest_area'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@rest_area, 40%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + } + } + + [feature = 'natural_glacier'][is_building = 'no'] { + [zoom >= 10][way_pixels > 3000], + [zoom >= 17] { + text-name: "[name]"; + text-size: @landcover-font-size; + [way_pixels > 12000] { text-size: @landcover-font-size-big; } + [way_pixels > 48000] { text-size: @landcover-font-size-bigger; } + text-fill: darken(@glacier, 40%); + text-face-name: @landcover-face-name; + text-halo-radius: 1; + text-halo-fill: rgba(255,255,255,0.6); + text-wrap-width: @landcover-wrap-width-size; + [way_pixels > 12000] {text-wrap-width: @landcover-wrap-width-size-big; } + [way_pixels > 48000] {text-wrap-width: @landcover-wrap-width-size-bigger; } + } + } + + [feature = 'aeroway_helipad'][zoom >= 16]::aeroway { + text-name: "[name]"; + text-size: 8; + text-fill: @airtransport; + text-dy: -10; + text-face-name: @bold-fonts; + text-halo-radius: 1; + text-placement: interior; + text-wrap-width: 30; + } + + [feature = 'aeroway_aerodrome'][zoom >= 10][zoom < 14]::aeroway { + text-name: "[name]"; + text-size: 8; + text-fill: darken(@airtransport, 15%); + text-dy: -10; + text-face-name: @oblique-fonts; + text-halo-radius: 1; + text-placement: interior; + text-wrap-width: 30; + } +} diff --git a/samples/Common Lisp/sample.lsp b/samples/Common Lisp/sample.lsp new file mode 100644 index 00000000..9bef6781 --- /dev/null +++ b/samples/Common Lisp/sample.lsp @@ -0,0 +1,21 @@ +;;;; -*- lisp -*- + +(in-package :foo) + +;;; Header comment. +(defvar *foo*) + +(eval-when (:execute :compile-toplevel :load-toplevel) + (defun add (x &optional y &key z) + (declare (ignore z)) + ;; Inline comment. + (+ x (or y 1)))) + +#| +Multi-line comment. +|# + +(defmacro foo (x &body b) + (if x + `(1+ ,x) ;After-line comment. + 42)) diff --git a/samples/Cool/list.cl b/samples/Cool/list.cl new file mode 100644 index 00000000..3d44813e --- /dev/null +++ b/samples/Cool/list.cl @@ -0,0 +1,26 @@ +(* This simple example of a list class is adapted from an example in the + Cool distribution. *) + +class List { + isNil() : Bool { true }; + head() : Int { { abort(); 0; } }; + tail() : List { { abort(); self; } }; + cons(i : Int) : List { + (new Cons).init(i, self) + }; +}; + +class Cons inherits List { + car : Int; -- The element in this list cell + cdr : List; -- The rest of the list + isNil() : Bool { false }; + head() : Int { car }; + tail() : List { cdr }; + init(i : Int, rest : List) : List { + { + car <- i; + cdr <- rest; + self; + } + }; +}; diff --git a/samples/Cool/sample.cl b/samples/Cool/sample.cl new file mode 100644 index 00000000..e8884990 --- /dev/null +++ b/samples/Cool/sample.cl @@ -0,0 +1,71 @@ +(* Refer to Alex Aiken, "The Cool Reference Manual": + http://theory.stanford.edu/~aiken/software/cool/cool-manual.pdf + for language specification. +*) + +-- Exhibit various language constructs +class Sample { + testCondition(x: Int): Bool { + if x = 0 + then false + else + if x < (1 + 2) * 3 + then true + else false + fi + fi + }; + + testLoop(y: Int): Bool { + while y > 0 loop + { + if not condition(y) + then y <- y / 2 + else y <- y - 1; + } + pool + }; + + testAssign(z: Int): Bool { + i : Int; + i <- ~z; + }; + + testCase(var: Sample): SELF_TYPE { + io : IO <- new IO; + case var of + a : A => io.out_string("Class type is A\n"); + b : B => io.out_string("Class type is B\n"); + s : Sample => io.out_string("Class type is Sample\n"); + o : Object => io.out_string("Class type is object\n"); + esac + }; + + testLet(i: Int): Int { + let (a: Int in + let(b: Int <- 3, c: Int <- 4 in + { + a <- 2; + a * b * 2 / c; + } + ) + ) + }; +}; + +-- Used to test subclasses +class A inherits Sample {}; +class B inherits A {}; + +class C { + main() : Int { + (new Sample).testLet(1) + }; +}; + +-- "Hello, world" example +class Main inherits IO { + main(): SELF_TYPE { + out_string("Hello, World.\n") + }; +}; diff --git a/samples/Emacs Lisp/.emacs.desktop b/samples/Emacs Lisp/.emacs.desktop new file mode 100644 index 00000000..499e44bb --- /dev/null +++ b/samples/Emacs Lisp/.emacs.desktop @@ -0,0 +1,29 @@ +;; -*- mode: emacs-lisp; coding: emacs-mule; -*- +;; -------------------------------------------------------------------------- +;; Desktop File for Emacs +;; -------------------------------------------------------------------------- +;; Created Sat Jan 3 12:46:35 2015 +;; Desktop file format version 206 +;; Emacs version 24.3.1 + +;; Global section: +(setq desktop-missing-file-warning nil) +(setq tags-file-name nil) +(setq tags-table-list nil) +(setq search-ring nil) +(setq regexp-search-ring nil) +(setq register-alist nil) +(setq file-name-history nil) + +;; Buffer section -- buffers listed in same order as in buffer list: +(desktop-create-buffer 206 + "/home/foo/bar" + "bar" + 'fundamental-mode + nil + 11572 + '(11554 nil) + nil + nil + '((buffer-file-coding-system . undecided-unix))) + diff --git a/samples/F#/Combinators.fs b/samples/F#/Combinators.fs new file mode 100644 index 00000000..409c524d --- /dev/null +++ b/samples/F#/Combinators.fs @@ -0,0 +1,49 @@ +namespace Nessos.FsPickler.Combinators + + open Nessos.FsPickler + open Nessos.FsPickler.Json + + /// Json pickling methods + [] + module Json = + + let private jsonSerializer = lazy(FsPickler.CreateJson(omitHeader = true)) + + /// + /// Pickles a value to Json. + /// + /// utilized pickler. + /// input value. + let pickle (pickler : Pickler<'T>) (value : 'T) : string = + jsonSerializer.Value.PickleToString (pickler, value) + + /// + /// Unpickles a value from Json. + /// + /// utilized pickler. + /// input pickle. + let unpickle (pickler : Pickler<'T>) (pickle : string) : 'T = + jsonSerializer.Value.UnPickleOfString (pickler, pickle) + + + /// Bson pickling methods + [] + module Bson = + + let private bsonPickler = lazy(FsPickler.CreateBson()) + + /// + /// Pickles a value to Bson. + /// + /// utilized pickler. + /// input value. + let pickle (pickler : Pickler<'T>) (value : 'T) : byte [] = + bsonPickler.Value.Pickle (pickler, value) + + /// + /// Unpickles a value from bson. + /// + /// utilized pickler. + /// input pickle. + let unpickle (pickler : Pickler<'T>) (pickle : byte []) : 'T = + bsonPickler.Value.UnPickle (pickler, pickle) \ No newline at end of file diff --git a/samples/F#/JsonFormat.fs b/samples/F#/JsonFormat.fs new file mode 100644 index 00000000..cf6aac61 --- /dev/null +++ b/samples/F#/JsonFormat.fs @@ -0,0 +1,65 @@ +namespace Nessos.FsPickler.Json + + open System + open System.IO + open System.Text + + open Newtonsoft.Json + + open Nessos.FsPickler + + /// + /// Factory methods for the Json serialization format. + /// + type JsonPickleFormatProvider internal (indent, omitHeader) as self = + + let isCustomSeq isTopLevelSequence = + isTopLevelSequence && self.OmitHeader && self.UseCustomTopLevelSequenceSeparator + + let mutable sequenceSeparator = " " + + member val Indent = indent with get,set + member val OmitHeader = omitHeader with get,set + member val UseCustomTopLevelSequenceSeparator = false with get,set + + member __.SequenceSeparator + with get () = sequenceSeparator + and set sep = + if sep <> null && String.IsNullOrWhiteSpace sep then + sequenceSeparator <- sep + else + invalidArg "SequenceSeparator" "should be non-null whitespace." + + interface ITextPickleFormatProvider with + member __.Name = "Json" + + // see discussion : https://github.com/nessos/FsPickler/issues/17 + member __.DefaultEncoding = new UTF8Encoding(false) :> Encoding + + member __.CreateWriter (stream, encoding, isTopLevelSequence, leaveOpen) = +#if NET40 + if leaveOpen then raise <| new NotSupportedException("'leaveOpen' not supported in .NET 40.") + let sw = new StreamWriter(stream, encoding) +#else + let sw = new StreamWriter(stream, encoding, 1024, leaveOpen) +#endif + let jw = new JsonTextWriter(sw) + new JsonPickleWriter(jw, __.OmitHeader, __.Indent, isCustomSeq isTopLevelSequence, sequenceSeparator, leaveOpen) :> _ + + member __.CreateReader (stream, encoding, isTopLevelSequence, leaveOpen) = +#if NET40 + if leaveOpen then raise <| new NotSupportedException("'leaveOpen' not supported in .NET 40.") + let sr = new StreamReader(stream, encoding) +#else + let sr = new StreamReader(stream, encoding, true, 1024, leaveOpen) +#endif + let jr = new JsonTextReader(sr) + new JsonPickleReader(jr, __.OmitHeader, isCustomSeq isTopLevelSequence, leaveOpen) :> _ + + member __.CreateWriter (textWriter, isTopLevelSequence, leaveOpen) = + let jw = new JsonTextWriter(textWriter) + new JsonPickleWriter(jw, __.OmitHeader, __.Indent, isCustomSeq isTopLevelSequence, sequenceSeparator, leaveOpen) :> _ + + member __.CreateReader (textReader, isTopLevelSequence, leaveOpen) = + let jr = new JsonTextReader(textReader) + new JsonPickleReader(jr, __.OmitHeader, isCustomSeq isTopLevelSequence, leaveOpen) :> _ \ No newline at end of file diff --git a/samples/F#/JsonReader.fs b/samples/F#/JsonReader.fs new file mode 100644 index 00000000..fdd90d3c --- /dev/null +++ b/samples/F#/JsonReader.fs @@ -0,0 +1,202 @@ +namespace Nessos.FsPickler.Json + + open System + open System.Collections.Generic + open System.Globalization + open System.IO + open System.Numerics + open System.Text + + open Newtonsoft.Json + + open Nessos.FsPickler + + /// + /// Json format deserializer + /// + type internal JsonPickleReader (jsonReader : JsonReader, omitHeader, isTopLevelSequence, leaveOpen) = + + do + jsonReader.CloseInput <- not leaveOpen + jsonReader.SupportMultipleContent <- isTopLevelSequence + + let isBsonReader = match jsonReader with :? Bson.BsonReader -> true | _ -> false + + let mutable depth = 0 + let arrayStack = new Stack () + do arrayStack.Push Int32.MinValue + + // do not write tag if omitting header or array element + let omitTag () = (omitHeader && depth = 0) || arrayStack.Peek() = depth - 1 + + interface IPickleFormatReader with + + member __.BeginReadRoot (tag : string) = + do jsonReader.Read() |> ignore + + if omitHeader then () else + + if jsonReader.TokenType <> JsonToken.StartObject then raise <| new FormatException("invalid json root object.") + else + do jsonReader.MoveNext() + let version = jsonReader.ReadPrimitiveAs false "FsPickler" + if version <> jsonFormatVersion then + let v = Version(version) + raise <| new FormatException(sprintf "Invalid FsPickler format version %O." version) + + let sTag = jsonReader.ReadPrimitiveAs false "type" + if tag <> sTag then + raise <| new InvalidPickleTypeException(tag, sTag) + + member __.EndReadRoot () = + if not omitHeader then jsonReader.Read() |> ignore + + member __.BeginReadObject (tag : string) = + + if not <| omitTag () then + jsonReader.ReadProperty tag + jsonReader.MoveNext () + + if isTopLevelSequence && depth = 0 then + arrayStack.Push depth + depth <- depth + 1 + ObjectFlags.IsSequenceHeader + + else + match jsonReader.TokenType with + | JsonToken.Null -> ObjectFlags.IsNull + | JsonToken.StartArray -> + jsonReader.MoveNext() + arrayStack.Push depth + depth <- depth + 1 + ObjectFlags.IsSequenceHeader + + | JsonToken.StartObject -> + do jsonReader.MoveNext() + depth <- depth + 1 + + if jsonReader.ValueAs () = "_flags" then + jsonReader.MoveNext() + let csvFlags = jsonReader.ValueAs() + jsonReader.MoveNext() + parseFlagCsv csvFlags + else + ObjectFlags.None + + | token -> raise <| new FormatException(sprintf "expected start of Json object but was '%O'." token) + + + member __.EndReadObject () = + if isTopLevelSequence && depth = 1 then + arrayStack.Pop () |> ignore + depth <- depth - 1 + jsonReader.Read() |> ignore + else + match jsonReader.TokenType with + | JsonToken.Null -> () + | JsonToken.EndObject -> depth <- depth - 1 + | JsonToken.EndArray -> + arrayStack.Pop() |> ignore + depth <- depth - 1 + + | token -> raise <| new FormatException(sprintf "expected end of Json object but was '%O'." token) + + if omitHeader && depth = 0 then () + else jsonReader.Read() |> ignore + + member __.SerializeUnionCaseNames = true + + member __.PreferLengthPrefixInSequences = false + member __.ReadNextSequenceElement () = + if isTopLevelSequence && depth = 1 then + jsonReader.TokenType <> JsonToken.None + else + jsonReader.TokenType <> JsonToken.EndArray + + member __.ReadCachedObjectId () = jsonReader.ReadPrimitiveAs false "id" + + member __.ReadBoolean tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag + member __.ReadByte tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag |> byte + member __.ReadSByte tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag |> sbyte + + member __.ReadInt16 tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag |> int16 + member __.ReadInt32 tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag |> int + member __.ReadInt64 tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag + + member __.ReadUInt16 tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag |> uint16 + member __.ReadUInt32 tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag |> uint32 + member __.ReadUInt64 tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag |> uint64 + + member __.ReadSingle tag = + if not <| omitTag () then + jsonReader.ReadProperty tag + jsonReader.MoveNext() + + let value = + match jsonReader.TokenType with + | JsonToken.Float -> jsonReader.ValueAs () |> single + | JsonToken.String -> Single.Parse(jsonReader.ValueAs(), CultureInfo.InvariantCulture) + | _ -> raise <| new FormatException("not a float.") + + jsonReader.Read() |> ignore + value + + member __.ReadDouble tag = + if not <| omitTag () then + jsonReader.ReadProperty tag + jsonReader.MoveNext() + + let value = + match jsonReader.TokenType with + | JsonToken.Float -> jsonReader.ValueAs () + | JsonToken.String -> Double.Parse(jsonReader.ValueAs(), CultureInfo.InvariantCulture) + | _ -> raise <| new FormatException("not a float.") + + jsonReader.Read() |> ignore + value + + member __.ReadChar tag = let value = jsonReader.ReadPrimitiveAs (omitTag ()) tag in value.[0] + member __.ReadString tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag + member __.ReadBigInteger tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag |> BigInteger.Parse + + member __.ReadGuid tag = + if isBsonReader then + jsonReader.ReadPrimitiveAs (omitTag ()) tag + else + jsonReader.ReadPrimitiveAs (omitTag ()) tag |> Guid.Parse + + member __.ReadTimeSpan tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag |> TimeSpan.Parse + member __.ReadDecimal tag = jsonReader.ReadPrimitiveAs (omitTag ()) tag |> decimal + + // BSON spec mandates the use of Unix time; + // this has millisecond precision which results in loss of accuracy w.r.t. ticks + // since the goal of FsPickler is to offer faithful representations of .NET objects + // we choose to override the spec and serialize ticks outright. + // see also https://json.codeplex.com/discussions/212067 + member __.ReadDate tag = + if isBsonReader then + let ticks = jsonReader.ReadPrimitiveAs (omitTag ()) tag + DateTime(ticks) + else + jsonReader.ReadPrimitiveAs (omitTag ()) tag + + member __.ReadBytes tag = + if not <| omitTag () then + jsonReader.ReadProperty tag + jsonReader.Read() |> ignore + + let bytes = + if jsonReader.TokenType = JsonToken.Null then null + elif isBsonReader then jsonReader.ValueAs () + else + let base64 = jsonReader.ValueAs () + Convert.FromBase64String base64 + + jsonReader.Read() |> ignore + + bytes + + member __.IsPrimitiveArraySerializationSupported = false + member __.ReadPrimitiveArray _ _ = raise <| new NotImplementedException() + + member __.Dispose () = (jsonReader :> IDisposable).Dispose() \ No newline at end of file diff --git a/samples/F#/JsonSerializer.fs b/samples/F#/JsonSerializer.fs new file mode 100644 index 00000000..15f4929a --- /dev/null +++ b/samples/F#/JsonSerializer.fs @@ -0,0 +1,85 @@ +namespace Nessos.FsPickler.Json + + open System + + open Nessos.FsPickler + + type internal OAttribute = System.Runtime.InteropServices.OptionalAttribute + type internal DAttribute = System.Runtime.InteropServices.DefaultParameterValueAttribute + + /// + /// Json pickler instance. + /// + type JsonSerializer = + inherit FsPicklerTextSerializer + + val private format : JsonPickleFormatProvider + + /// + /// Initializes a new Json pickler instance. + /// + /// indent out Json pickles. + /// omit FsPickler header in Json pickles. + /// specify a custom type name converter. + new ([] ?indent, [] ?omitHeader, [] ?typeConverter) = + let indent = defaultArg indent false + let omitHeader = defaultArg omitHeader false + let json = new JsonPickleFormatProvider(indent, omitHeader) + { + inherit FsPicklerTextSerializer(json, ?typeConverter = typeConverter) + format = json + } + + /// + /// Gets or sets whether Json output should be indented. + /// + member x.Indent + with get () = x.format.Indent + and set b = x.format.Indent <- b + + /// + /// Gets or sets whether FsPickler headers should be ignored in pickle format. + /// + member x.OmitHeader + with get () = x.format.OmitHeader + and set b = x.format.OmitHeader <- b + + /// + /// Gets or sets a non-null whitespace string that serves as a custom, top-level sequence separator. + /// + member x.SequenceSeparator + with get () = x.format.SequenceSeparator + and set sep = x.format.SequenceSeparator <- sep + + /// + /// Gets or sets whether top-level sequences should be serialized using the custom separator. + /// + member x.UseCustomTopLevelSequenceSeparator + with get () = x.format.UseCustomTopLevelSequenceSeparator + and set e = x.format.UseCustomTopLevelSequenceSeparator <- e + + /// + /// BSON pickler instance. + /// + type BsonSerializer([] ?typeConverter) = + inherit FsPicklerSerializer(new BsonPickleFormatProvider(), ?typeConverter = typeConverter) + + + /// FsPickler static methods. + type FsPickler = + + /// + /// Initializes a new Json pickler instance. + /// + /// indent out Json pickles. + /// omit FsPickler header in Json pickles. + /// specify a custom type name converter. + static member CreateJson([] ?indent, [] ?omitHeader, [] ?typeConverter) = + new JsonSerializer(?indent = indent, ?omitHeader = omitHeader, ?typeConverter = typeConverter) + + /// + /// Initializes a new Bson pickler instance. + /// + /// specify a custom type name converter. + static member CreateBson([] ?typeConverter) = + new BsonSerializer(?typeConverter = typeConverter) \ No newline at end of file diff --git a/samples/F#/JsonWriter.fs b/samples/F#/JsonWriter.fs new file mode 100644 index 00000000..bbb6ff24 --- /dev/null +++ b/samples/F#/JsonWriter.fs @@ -0,0 +1,142 @@ +namespace Nessos.FsPickler.Json + + open System + open System.IO + open System.Collections.Generic + + open Newtonsoft.Json + + open Nessos.FsPickler + + /// + /// Json format serializer. + /// + type internal JsonPickleWriter (jsonWriter : JsonWriter, omitHeader, indented, isTopLevelSequence, separator, leaveOpen) = + + do + jsonWriter.Formatting <- if indented then Formatting.Indented else Formatting.None + jsonWriter.CloseOutput <- not leaveOpen + + let isBsonWriter = match jsonWriter with :? Bson.BsonWriter -> true | _ -> false + + let mutable depth = 0 + let mutable isTopLevelSequenceHead = false + let mutable currentValueIsNull = false + + let arrayStack = new Stack () + do arrayStack.Push Int32.MinValue + + // do not write tag if omitting header or array element + let omitTag () = (omitHeader && depth = 0) || arrayStack.Peek() = depth - 1 + + interface IPickleFormatWriter with + + member __.BeginWriteRoot (tag : string) = + if omitHeader then () else + + jsonWriter.WriteStartObject() + writePrimitive jsonWriter false "FsPickler" jsonFormatVersion + writePrimitive jsonWriter false "type" tag + + member __.EndWriteRoot () = + if not omitHeader then jsonWriter.WriteEnd() + + member __.BeginWriteObject (tag : string) (flags : ObjectFlags) = + + if not <| omitTag () then + jsonWriter.WritePropertyName tag + + if flags.HasFlag ObjectFlags.IsNull then + currentValueIsNull <- true + jsonWriter.WriteNull() + + elif flags.HasFlag ObjectFlags.IsSequenceHeader then + if isTopLevelSequence && depth = 0 then + isTopLevelSequenceHead <- true + else + jsonWriter.WriteStartArray() + + arrayStack.Push depth + depth <- depth + 1 + else + jsonWriter.WriteStartObject() + depth <- depth + 1 + + if flags = ObjectFlags.None then () + else + let flagCsv = mkFlagCsv flags + writePrimitive jsonWriter false "_flags" flagCsv + + member __.EndWriteObject () = + if currentValueIsNull then + currentValueIsNull <- false + else + depth <- depth - 1 + if arrayStack.Peek () = depth then + if isTopLevelSequence && depth = 0 then () + else + jsonWriter.WriteEndArray() + + arrayStack.Pop () |> ignore + else + jsonWriter.WriteEndObject() + + member __.SerializeUnionCaseNames = true + + member __.PreferLengthPrefixInSequences = false + member __.WriteNextSequenceElement hasNext = + if isTopLevelSequence && depth = 1 then + if isTopLevelSequenceHead then + isTopLevelSequenceHead <- false + else + jsonWriter.WriteWhitespace separator + + member __.WriteCachedObjectId id = writePrimitive jsonWriter false "id" id + + member __.WriteBoolean (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + member __.WriteByte (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + member __.WriteSByte (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + + member __.WriteInt16 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + member __.WriteInt32 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + member __.WriteInt64 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + + member __.WriteUInt16 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + member __.WriteUInt32 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + member __.WriteUInt64 (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + + member __.WriteSingle (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + member __.WriteDouble (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + member __.WriteDecimal (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag (string value) + + member __.WriteChar (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + member __.WriteString (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + member __.WriteBigInteger (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag (string value) + + member __.WriteGuid (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag value + member __.WriteTimeSpan (tag : string) value = writePrimitive jsonWriter (omitTag ()) tag (string value) + + // BSON spec mandates the use of Unix time; + // this has millisecond precision which results in loss of accuracy w.r.t. ticks + // since the goal of FsPickler is to offer faithful representations of .NET objects + // we choose to override the spec and serialize ticks outright. + // see also https://json.codeplex.com/discussions/212067 + member __.WriteDate (tag : string) value = + if isBsonWriter then + writePrimitive jsonWriter (omitTag ()) tag value.Ticks + else + writePrimitive jsonWriter (omitTag ()) tag value + + member __.WriteBytes (tag : string) (value : byte []) = + if not <| omitTag () then + jsonWriter.WritePropertyName tag + + if obj.ReferenceEquals(value, null) then + jsonWriter.WriteNull() + else + jsonWriter.WriteValue value + + member __.IsPrimitiveArraySerializationSupported = false + member __.WritePrimitiveArray _ _ = raise <| NotSupportedException() + + member __.Dispose () = jsonWriter.Flush() \ No newline at end of file diff --git a/samples/F#/PerformanceTesters.fs b/samples/F#/PerformanceTesters.fs new file mode 100644 index 00000000..c5eb20d2 --- /dev/null +++ b/samples/F#/PerformanceTesters.fs @@ -0,0 +1,68 @@ +namespace Nessos.FsPickler.Tests + + open PerfUtil + open PerfUtil.NUnit + + open NUnit.Framework + + open Nessos.FsPickler + open Nessos.FsPickler.Json + + [] + type PerfTester () = + inherit NUnitPerf () + + let tests = PerfTest.OfModuleMarker () + + override __.PerfTests = tests + + + type ``Serializer Comparison`` () = + inherit PerfTester() + + let fsp = FsPickler.initBinary() + let bfs = new BinaryFormatterSerializer() :> Serializer + let ndc = new NetDataContractSerializer() :> Serializer + let jdn = new JsonDotNetSerializer() :> Serializer + let bdn = new JsonDotNetBsonSerializer () :> Serializer + let pbn = new ProtoBufSerializer() :> Serializer + let ssj = new ServiceStackJsonSerializer() :> Serializer + let sst = new ServiceStackTypeSerializer() :> Serializer + + let comparer = new WeightedComparer(spaceFactor = 0.2, leastAcceptableImprovementFactor = 1.) + let tester = new ImplementationComparer<_>(fsp, [bfs;ndc;jdn;bdn;pbn;ssj;sst], throwOnError = true, warmup = true, comparer = comparer) + + override __.PerfTester = tester :> _ + + + type ``FsPickler Formats Comparison`` () = + inherit PerfTester () + + let binary = FsPickler.initBinary() + let json = FsPickler.initJson() + let bson = FsPickler.initBson() + let xml = FsPickler.initXml() + + let tester = new ImplementationComparer<_>(binary, [json ; bson; xml], warmup = true, throwOnError = false) + + override __.PerfTester = tester :> _ + + + type ``Past FsPickler Versions Comparison`` () = + inherit PerfTester () + + let persistResults = true + let persistenceFile = "fspPerf.xml" + + let fsp = FsPickler.initBinary() + let version = typeof.Assembly.GetName().Version + let comparer = new WeightedComparer(spaceFactor = 0.2, leastAcceptableImprovementFactor = 0.8) + let tester = + new PastImplementationComparer( + fsp, version, historyFile = persistenceFile, throwOnError = true, warmup = true, comparer = comparer) + + override __.PerfTester = tester :> _ + + [] + member __.Persist() = + if persistResults then tester.PersistCurrentResults () \ No newline at end of file diff --git a/samples/F#/PerformanceTests.fs b/samples/F#/PerformanceTests.fs new file mode 100644 index 00000000..c3d01356 --- /dev/null +++ b/samples/F#/PerformanceTests.fs @@ -0,0 +1,207 @@ +namespace Nessos.FsPickler.Tests + + open System + open System.Collections.Generic + + open PerfUtil + + open Nessos.FsPickler + open Nessos.FsPickler.Tests.Serializer + open Nessos.FsPickler.Tests.TestTypes + + module PerformanceTests = + + type Marker = class end + + let guid = Guid.NewGuid() + + [] + let ``Value: Guid`` s = roundtrip guid s + + let date = DateTime.Now + + [] + let ``Value: DateTime`` s = roundtrip date s + + [] + let ``Value: String`` s = roundtrip stringValue s + + + let boxed = box ([| 1 .. 1000 |], "lorem ipsum") + + [] + let ``Boxed Object`` s = roundtrip boxed s + + let fsClass = new Class(42, stringValue) + + [] + let ``Class: Simple F# Class`` s = roundtrip fsClass s + + let serializableClass = new SerializableClass<_>(42, stringValue, [|1..1000|]) + + [] + let ``Class: ISerializable`` s = roundtrip serializableClass s + + let boxedClass = box(Some 42) + + [] + let ``Subtype Resolution`` s = roundtrip boxedClass s + + let floatArray = Array.init 100000 (fun i -> float i) + + [] + let ``Array: Float`` s = roundtrip floatArray s + + let intArray = Array.init 100000 id + + [] + let ``Array: Int`` s = roundtrip intArray s + + let stringArray = Array.init 10000 (fun i -> stringValue + string i) + + [] + let ``Array: String`` s = roundtrip stringArray s + + let kvarr = [|1..10000|] |> Array.map (fun i -> i, string i) + + [] + let ``Array: Key-Value Pairs`` s = roundtrip kvarr s + + let duArray = [| for i in 1 .. 10000 -> (Something ("asdasdasdas", i)) |] + + [] + let ``Array: Discriminated Unions`` s = roundtrip duArray s + + let objArray = + [| + box 2; box 3; box "hello" ; box <| Some 3; box(2,3) ; + box <| new Class(2, stringValue) ; box <| new SerializableClass(2, stringValue, Some 12); + box stringValue + |] + + [] + let ``Array: Objects`` s = roundtrip objArray s + + + let array3D = Array3D.init 100 100 100 (fun i j k -> float (i * j + k)) + + [] + let ``Array: Rank-3 Float`` s = roundtrip array3D s + + let bclDict = dict [ for i in 1 .. 1000 -> (string i, i)] + + [] + let ``.NET Dictionary`` s = roundtrip bclDict s + + let bclStack = new Stack([for i in 1 .. 1000 -> string i]) + + [] + let ``.NET Stack`` s = roundtrip bclStack s + + let bclList = new List([for i in 1 .. 1000 -> string i, i]) + + [] + let ``.NET List`` s = roundtrip bclList s + + let bclSet = new SortedSet<_>([for i in 1 .. 1000 -> string i]) + + [] + let ``.NET Set`` s = roundtrip bclSet s + + let smallTuple = (1, DateTime.Now,"hello") + + [] + let ``FSharp: Tuple Small`` s = roundtrip smallTuple s + + let largeTuple = (stringValue, 1, 2, 3, true, "", Some(3.14, [2]), 3, 2, 1, stringValue) + + [] + let ``FSharp: Tuple Large`` s = + roundtrip largeTuple s + + let intList = [1..1000] + + [] + let ``FSharp: List Int`` s = roundtrip intList s + + let stringList = [ for i in 1 .. 1000 -> stringValue + string i ] + + [] + let ``FSharp: List String`` s = roundtrip stringList s + + let pairList = [ for i in 1 .. 1000 -> (string i, i) ] + + [] + let ``FSharp: List Key-Value`` s = roundtrip pairList s + + let nestedLst = let n = [1..1000] in [for _ in 1 .. 100 -> n] + + [] + let ``FSharp: List Nested`` s = roundtrip nestedLst s + + let union = SomethingElse(stringValue, 42, box (Some 42)) + + [] + let ``FSharp: Union`` s = roundtrip union s + + let record = { Int = 42 ; String = stringValue ; Tuple = (13, "") } + + [] + let ``FSharp: Record`` s = roundtrip record s + + let peano = int2Peano 100 + + [] + let ``FSharp: Peano Rectype`` s = roundtrip peano s + + let closure = (@) [ Some([1..100], Set.ofList [1..100]) ] + + [] + let ``FSharp: Curried Function`` s = roundtrip closure s + + let binTree = mkTree 10 + + [] + let ``FSharp: Binary Tree`` s = roundtrip binTree s + + let intSet = [1..1000] |> List.map string |> set + + [] + let ``FSharp: Set`` s = roundtrip intSet s + + let fsMap = [1..1000] |> Seq.map (fun i -> (string i,i)) |> Map.ofSeq + + [] + let ``FSharp: Map`` s = roundtrip fsMap s + + let testType = typeof> + + [] + let ``Reflection: Type`` s = roundtrip testType s + + let quotationSmall = <@ fun x -> pown 2 x @> + + let quotationLarge = + <@ + async { + let rec fibAsync n = + async { + match n with + | _ when n < 0 -> return invalidArg "negative" "n" + | _ when n < 2 -> return n + | n -> + let! fn = fibAsync (n-1) + let! fnn = fibAsync (n-2) + return fn + fnn + } + + let! values = [1..100] |> Seq.map fibAsync |> Async.Parallel + return Seq.sum values + } + @> + + [] + let ``FSharp: Quotation Small`` s = roundtrip quotationSmall s + + [] + let ``FSharp: Quotation Large`` s = roundtrip quotationLarge s \ No newline at end of file diff --git a/samples/F#/sample.fs b/samples/F#/sample.fs new file mode 100644 index 00000000..2b690f10 --- /dev/null +++ b/samples/F#/sample.fs @@ -0,0 +1,15 @@ +module Sample + +open System + +type Foo = + { + Bar : string + } + +type Baz = interface end + +let Sample1(xs : int list) : string = + xs + |> List.map (fun x -> string x) + |> String.concat "," diff --git a/samples/Forth/asm.fr b/samples/Forth/asm.fr new file mode 100644 index 00000000..73faf776 --- /dev/null +++ b/samples/Forth/asm.fr @@ -0,0 +1,244 @@ +\ Copyright 2013-2014 Lars Brinkhoff + +\ Assembler for x86. + +\ Adds to FORTH vocabulary: ASSEMBLER CODE ;CODE. +\ Creates ASSEMBLER vocabulary with: END-CODE and x86 opcodes. + +\ Conventional prefix syntax: " ,". +\ Addressing modes: +\ - immediate: "n #" +\ - direct: n +\ - register: +\ - indirect: " )" +\ - indirect with displacement: "n )#" +\ - indexed: not supported yet + +require lib/common.fth +require search.fth + +vocabulary assembler +also assembler definitions + +\ Access to the target image. +' header, defer header, is header, +' cell defer cell is cell +' dp defer dp is dp +0 value delta + +: aligned cell + 1 - cell negate nand invert ; +: align dp @ aligned dp ! ; +: allot dp +! ; +: here dp @ ; +: cells cell * ; +: c! delta + c! ; +: c, here c! 1 allot ; +: h, dup c, 8 rshift c, ; +: , dup h, 16 rshift h, ; + +base @ hex + +\ This constant signals that an operand is not a direct address. +deadbeef constant -addr + +\ Assembler state. +variable opcode +variable d +variable s +variable dir? +variable mrrm defer ?mrrm, +variable sib defer ?sib, +variable disp defer ?disp, +variable imm defer ?imm, +defer imm, +defer immediate-opcode +defer reg +defer ?opsize + +\ Set opcode. And destination: register or memory. +: opcode! 3@ is immediate-opcode >r opcode ! ; +: !reg dir? @ if 2 d ! then dir? off ; +: !mem dir? off ; + +\ Set bits in mod/reg/rm byte. +: -mrrm ['] nop is ?mrrm, ; +: mod! mrrm c0 !bits ; +: reg@ mrrm 38 @bits ; +: reg! mrrm 38 !bits ; +: rm@ mrrm 7 @bits ; +: rm! rm@ 3 lshift reg! mrrm 7 !bits ; +: reg>opcode rm@ opcode 07 !bits ; +: opcode>reg opcode @ dup 3 rshift rm! 8 rshift opcode ! ; + +\ Write parts of instruction to memory. +: ds d @ s @ + ; +: ?twobyte dup FF > if dup 8 rshift c, then ; +: opcode, opcode @ ?twobyte ds + c, ; +: mrrm, mrrm @ c, ; +: sib, sib @ c, ; +: imm8, imm @ c, ; +: imm16, imm @ h, ; +: imm32, imm @ , ; +: disp8, disp @ c, ; +: disp32, disp @ , ; + +\ Set operand size. +: -opsize 2drop r> drop ; +: opsize! is imm, s ! ['] -opsize is ?opsize ; +: !op8 0 ['] imm8, ?opsize ; +: !op32 1 ['] imm32, ?opsize ; +: !op16 1 ['] imm16, ?opsize 66 c, ; + +\ Set SIB byte. +: !sib ['] sib, is ?sib, ; +: sib! 3 lshift + sib ! !sib ; + +\ Set displacement. +: byte? -80 80 within ; +: disp! is ?disp, disp ! ; +: !disp8 ['] disp8, disp! ; +: !disp32 ['] disp32, disp! ; +: !disp ( a -- u ) dup byte? if !disp8 40 else !disp32 80 then ; +: -pc here 5 + negate ; +: relative -pc disp +! ; + +\ Set immediate operand. +: imm! imm ! ['] imm, is ?imm, ; + +\ Implements addressing modes: register, indirect, indexed, and direct. +: reg1 rm! !reg ; +: reg2 3 lshift reg! ; +: !reg2 ['] reg2 is reg ; +: ind dup mod! rm! !mem !reg2 ; +: ind# swap !disp + ind ; +: idx 04 ind sib! ; +: idx# rot !disp 04 + ind sib! ; +: addr !disp32 05 ind ; + +\ Reset assembler state. +: 0opsize ['] opsize! is ?opsize ; +: 0ds d off s off ; +: 0reg ['] reg1 is reg ; +: 0mrrm c0 mrrm ! ['] mrrm, is ?mrrm, ; +: 0sib ['] nop is ?sib, ; +: 0disp ['] nop is ?disp, ; +: 0imm imm off ['] nop is ?imm, 0 is imm, ; +: 0asm 0imm 0disp 0reg 0ds 0mrrm 0sib 0opsize dir? on ; + +\ Enter and exit assembler mode. +: start-code also assembler 0asm ; +: end-code align previous ; + +\ Implements addressing mode: immediate. +: imm8? imm @ byte? ; +: ?sign-extend d off imm8? if 2 d ! ['] imm8, is ?imm, then ; +: alu# opcode @ reg! 80 opcode ! ?sign-extend ; +: mov# B0 s @ 3 lshift + rm@ + opcode ! 0ds -mrrm ; +: push# imm8? if ['] imm8, 6A else ['] imm32, 68 then dup opcode ! rm! is ?imm, ; +: test# F6 opcode ! ; +: imm-op imm! immediate-opcode ; + +\ Process one operand. All operands except a direct address +\ have the stack picture ( n*x xt -addr ). +: addr? dup -addr <> ; +: op addr? if addr else drop execute then ; + +\ Define instruction formats. +: instruction, opcode! opcode, ?mrrm, ?sib, ?disp, ?imm, 0asm ; +: mnemonic ( u a "name" -- ) create ['] nop 3, does> instruction, ; +: format: create ] !csp does> mnemonic ; +: immediate: ' latestxt >body ! ; + +\ Instruction formats. +format: 0op -mrrm ; +format: 1reg op reg>opcode 0ds -mrrm ; +format: 1op opcode>reg op d off ; +format: 2op op op ; +format: 2op-d op op d off ; +format: 2op-ds op op 0ds ; +format: 1addr op relative -mrrm ; +format: 1imm8 !op8 op -mrrm ; + +\ Instruction mnemonics. +00 2op add, immediate: alu# +08 2op or, immediate: alu# +0F44 2op-ds cmove, \ Todo: other condition codes. +0FB6 2op-ds movzx, +0FBE 2op-ds movsx, +10 2op adc, immediate: alu# +18 2op sbb, immediate: alu# +20 2op and, immediate: alu# +26 0op es, +28 2op sub, immediate: alu# +2E 0op cs, +30 2op xor, immediate: alu# +36 0op ss, +38 2op cmp, immediate: alu# +3E 0op ds, +50 1reg push, immediate: push# +58 1reg pop, +64 0op fs, +65 0op gs, +\ 70 jcc +84 2op-d test, immediate: test# +86 2op-d xchg, +88 2op mov, immediate: mov# +8D 2op-ds lea, +\ 8F/0 pop, rm +90 0op nop, +C3 0op ret, +\ C6/0 immediate mov to r/m +\ C7/0 immediate mov to r/m +CD 1imm8 int, +E8 1addr call, +E9 1addr jmp, +\ EB jmp rel8 +F0 0op lock, +F2 0op rep, +F3 0op repz, +F4 0op hlt, +F5 0op cmc, +F610 1op not, +F618 1op neg, +F8 0op clc, +F9 0op stc, +FA 0op cli, +FB 0op sti, +FC 0op cld, +FD 0op std, +\ FE 0 inc rm +\ FF 1 dec rm +\ FF 2 call rm +\ FF 4 jmp rm +\ FF 6 push rm + +: sp? dup 4 = ; + +\ Addressing mode syntax: immediate, indirect, and displaced indirect. +: # ['] imm-op -addr ; +: ) 2drop sp? if 4 ['] idx else ['] ind then -addr 0reg 0opsize ; +: )# 2drop sp? if 4 ['] idx# else ['] ind# then -addr 0reg 0opsize ; + +\ Define registers. +: reg8 create , does> @ ['] reg -addr !op8 ; +: reg16 create , does> @ ['] reg -addr !op16 ; +: reg32 create , does> @ ['] reg -addr !op32 ; +: reg: dup reg8 dup reg16 dup reg32 1+ ; + +\ Register names. +0 +reg: al ax eax reg: cl cx ecx reg: dl dx edx reg: bl bx ebx +reg: ah sp esp reg: ch bp ebp reg: dh si esi reg: bh di edi +drop + +\ Runtime for ;CODE. CODE! is defined elsewhere. +: (;code) r> code! ; + +base ! only forth definitions also assembler + +\ Standard assembler entry points. +: code parse-name header, ?code, start-code ; +: ;code postpone (;code) reveal postpone [ ?csp start-code ; immediate + +0asm +previous diff --git a/samples/Forth/core.fs b/samples/Forth/core.fs new file mode 100644 index 00000000..4a13e217 --- /dev/null +++ b/samples/Forth/core.fs @@ -0,0 +1,252 @@ +: immediate lastxt @ dup c@ negate swap c! ; + +: \ source nip >in ! ; immediate \ Copyright 2004, 2012 Lars Brinkhoff + +: char \ ( "word" -- char ) + bl-word here 1+ c@ ; + +: ahead here 0 , ; + +: resolve here swap ! ; + +: ' bl-word here find 0branch [ ahead ] exit [ resolve ] 0 ; + +: postpone-nonimmediate [ ' literal , ' compile, ] literal , ; + +: create dovariable_code header, reveal ; + +create postponers + ' postpone-nonimmediate , + ' abort , + ' , , + +: word \ ( char "string" -- caddr ) + drop bl-word here ; + +: postpone \ ( C: "word" -- ) + bl word find 1+ cells postponers + @ execute ; immediate + +: unresolved \ ( C: "word" -- orig ) + postpone postpone postpone ahead ; immediate + +: chars \ ( n1 -- n2 ) + ; + +: else \ ( -- ) ( C: orig1 -- orig2 ) + unresolved branch swap resolve ; immediate + +: if \ ( flag -- ) ( C: -- orig ) + unresolved 0branch ; immediate + +: then \ ( -- ) ( C: orig -- ) + resolve ; immediate + +: [char] \ ( "word" -- ) + char postpone literal ; immediate + +: (does>) lastxt @ dodoes_code over >code ! r> swap >does ! ; + +: does> postpone (does>) ; immediate + +: begin \ ( -- ) ( C: -- dest ) + here ; immediate + +: while \ ( x -- ) ( C: dest -- orig dest ) + unresolved 0branch swap ; immediate + +: repeat \ ( -- ) ( C: orig dest -- ) + postpone branch , resolve ; immediate + +: until \ ( x -- ) ( C: dest -- ) + postpone 0branch , ; immediate + +: recurse lastxt @ compile, ; immediate + +: pad \ ( -- addr ) + here 1024 + ; + +: parse \ ( char "string" -- addr n ) + pad >r begin + source? if else 0 0 then + while + r@ c! r> 1+ >r + repeat 2drop pad r> over - ; + +: ( \ ( "string" -- ) + [ char ) ] literal parse 2drop ; immediate + \ TODO: If necessary, refill and keep parsing. + +: string, ( addr n -- ) + here over allot align swap cmove ; + +: (s") ( -- addr n ) ( R: ret1 -- ret2 ) + r> dup @ swap cell+ 2dup + aligned >r swap ; + +create squote 128 allot + +: s" ( "string" -- addr n ) + state @ if + postpone (s") [char] " parse dup , string, + else + [char] " parse >r squote r@ cmove squote r> + then ; immediate + +: (abort") ( ... addr n -- ) ( R: ... -- ) + cr type cr abort ; + +: abort" ( ... x "string" -- ) ( R: ... -- ) + postpone if postpone s" postpone (abort") postpone then ; immediate + +\ ---------------------------------------------------------------------- + +( Core words. ) + +\ TODO: # +\ TODO: #> +\ TODO: #s + +: and ( x y -- x&y ) nand invert ; + +: * 1 2>r 0 swap begin r@ while + r> r> swap 2dup dup + 2>r and if swap over + swap then dup + + repeat r> r> 2drop drop ; + +\ TODO: */mod + +: +loop ( -- ) ( C: nest-sys -- ) + postpone (+loop) postpone 0branch , postpone unloop ; immediate + +: space bl emit ; + +: ?.- dup 0 < if [char] - emit negate then ; + +: digit [char] 0 + emit ; + +: (.) base @ /mod ?dup if recurse then digit ; + +: ." ( "string" -- ) postpone s" postpone type ; immediate + +: . ( x -- ) ?.- (.) space ; + +: postpone-number ( caddr -- ) + 0 0 rot count >number dup 0= if + 2drop nip + postpone (literal) postpone (literal) postpone , + postpone literal postpone , + else + ." Undefined: " type cr abort + then ; + +' postpone-number postponers cell+ ! + +: / ( x y -- x/y ) /mod nip ; + +: 0< ( n -- flag ) 0 < ; + +: 1- ( n -- n-1 ) -1 + ; + +: 2! ( x1 x2 addr -- ) swap over ! cell+ ! ; + +: 2* ( n -- 2n ) dup + ; + +\ Kernel: 2/ + +: 2@ ( addr -- x1 x2 ) dup cell+ @ swap @ ; + +\ Kernel: 2drop +\ Kernel: 2dup + +\ TODO: 2over ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 ) +\ 3 pick 3 pick ; + +\ TODO: 2swap + +\ TODO: <# + +: abs ( n -- |n| ) + dup 0< if negate then ; + +\ TODO: accept + +: c, ( n -- ) + here c! 1 chars allot ; + +: char+ ( n1 -- n2 ) + 1+ ; + +: constant create , does> @ ; + +: decimal ( -- ) + 10 base ! ; + +: depth ( -- n ) + data_stack 100 cells + 'SP @ - /cell / 2 - ; + +: do ( n1 n2 -- ) ( R: -- loop-sys ) ( C: -- do-sys ) + postpone 2>r here ; immediate + +\ TODO: environment? +\ TODO: evaluate +\ TODO: fill +\ TODO: fm/mod ) +\ TODO: hold + +: j ( -- x1 ) ( R: x1 x2 x3 -- x1 x2 x3 ) + 'RP @ 3 cells + @ ; + +\ TODO: leave + +: loop ( -- ) ( C: nest-sys -- ) + postpone 1 postpone (+loop) + postpone 0branch , + postpone unloop ; immediate + +: lshift begin ?dup while 1- swap dup + swap repeat ; + +: rshift 1 begin over while dup + swap 1- swap repeat nip + 2>r 0 1 begin r@ while + r> r> 2dup swap dup + 2>r and if swap over + swap then dup + + repeat r> r> 2drop drop ; + +: max ( x y -- max[x,y] ) + 2dup > if drop else nip then ; + +\ Kernel: min +\ TODO: mod +\ TODO: move + +: (quit) ( R: ... -- ) + return_stack 100 cells + 'RP ! + 0 'source-id ! tib ''source ! #tib ''#source ! + postpone [ + begin + refill + while + interpret state @ 0= if ." ok" cr then + repeat + bye ; + +' (quit) ' quit >body cell+ ! + +\ TODO: s>d +\ TODO: sign +\ TODO: sm/rem + +: spaces ( n -- ) + 0 do space loop ; + +\ TODO: u. + +: signbit ( -- n ) -1 1 rshift invert ; + +: xor ( x y -- x^y ) 2dup nand >r r@ nand swap r> nand nand ; + +: u< ( x y -- flag ) signbit xor swap signbit xor > ; + +\ TODO: um/mod + +: variable ( "word" -- ) + create /cell allot ; + +: ['] \ ( C: "word" -- ) + ' postpone literal ; immediate diff --git a/samples/Forth/tools.4TH b/samples/Forth/tools.4TH new file mode 100644 index 00000000..b08a29fe --- /dev/null +++ b/samples/Forth/tools.4TH @@ -0,0 +1,133 @@ +\ -*- forth -*- Copyright 2004, 2013 Lars Brinkhoff + +( Tools words. ) + +: .s ( -- ) + [char] < emit depth (.) ." > " + 'SP @ >r r@ depth 1- cells + + begin + dup r@ <> + while + dup @ . + /cell - + repeat r> 2drop ; + +: ? @ . ; + +: c? c@ . ; + +: dump bounds do i ? /cell +loop cr ; + +: cdump bounds do i c? loop cr ; + +: again postpone branch , ; immediate + +: see-find ( caddr -- end xt ) + >r here lastxt @ + begin + dup 0= abort" Undefined word" + dup r@ word= if r> drop exit then + nip dup >nextxt + again ; + +: cabs ( char -- |char| ) dup 127 > if 256 swap - then ; + +: xt. ( xt -- ) + ( >name ) count cabs type ; + +: xt? ( xt -- flag ) + >r lastxt @ begin + ?dup + while + dup r@ = if r> 2drop -1 exit then + >nextxt + repeat r> drop 0 ; + +: disassemble ( x -- ) + dup xt? if + ( >name ) count + dup 127 > if ." postpone " then + cabs type + else + . + then ; + +: .addr dup . ; + +: see-line ( addr -- ) + cr ." ( " .addr ." ) " @ disassemble ; + +: see-word ( end xt -- ) + >r ." : " r@ xt. + r@ >body do i see-line /cell +loop + ." ;" r> c@ 127 > if ." immediate" then ; + +: see bl word see-find see-word cr ; + +: #body bl word see-find >body - ; + +: type-word ( end xt -- flag ) + xt. space drop 0 ; + +: traverse-dictionary ( in.. xt -- out.. ) + \ xt execution: ( in.. end xt2 -- in.. 0 | in.. end xt2 -- out.. true ) + >r here lastxt @ begin + ?dup + while + r> 2dup >r >r execute + if r> r> 2drop exit then + r> dup >nextxt + repeat r> 2drop ; + +: words ( -- ) + ['] type-word traverse-dictionary cr ; + +\ ---------------------------------------------------------------------- + +( Tools extension words. ) + +\ ;code + +\ assembler + +\ in kernel: bye + +\ code + +\ cs-pick + +\ cs-roll + +\ editor + +: forget ' dup >nextxt lastxt ! 'here ! reveal ; + +\ Kernel: state + +\ [else] + +\ [if] + +\ [then] + +\ ---------------------------------------------------------------------- + +( Forth2012 tools extension words. ) + +\ TODO: n>r + +\ TODO: nr> + +\ TODO: synonym + +: [undefined] bl-word find nip 0= ; immediate + +: [defined] postpone [undefined] invert ; immediate + +\ ---------------------------------------------------------------------- + +: @+ ( addr -- addr+/cell x ) dup cell+ swap @ ; + +: !+ ( x addr -- addr+/cell ) tuck ! cell+ ; + +: -rot swap >r swap r> ; diff --git a/samples/GAP/bugfix.tst b/samples/GAP/bugfix.tst new file mode 100644 index 00000000..be4bd975 --- /dev/null +++ b/samples/GAP/bugfix.tst @@ -0,0 +1,161 @@ +gap> START_TEST("Test for various former bugs"); + + +gap> # The following used to trigger an error starting with: +gap> # "SolutionMat: matrix and vector incompatible called from" +gap> K:=AbelianPcpGroup([3,3,3]);; +gap> A:=Subgroup(K,[K.1]);; +gap> cr:=CRRecordBySubgroup(K,A);; +gap> ExtensionsCR(cr);; + + +# Comparing homomorphisms used to be broken +gap> K:=AbelianPcpGroup(1,[3]);; +gap> hom1:=GroupHomomorphismByImages(K,K,[K.1],[K.1]);; +gap> hom2:=GroupHomomorphismByImages(K,K,[K.1^2],[K.1^2]);; +gap> hom1=hom2; +true +gap> hom1=IdentityMapping(K); +true +gap> hom2=IdentityMapping(K); +true + + +gap> # The following incorrectly triggered an error at some point +gap> IsTorsionFree(ExamplesOfSomePcpGroups(5)); +true + + +gap> # Verify IsGeneratorsOfMagmaWithInverses warnings are silenced +gap> IsGeneratorsOfMagmaWithInverses(GeneratorsOfGroup(ExamplesOfSomePcpGroups(5))); +true + + +gap> # Check for a bug reported 2012-01-19 by Robert Morse +gap> g := PcGroupToPcpGroup(SmallGroup(48,1)); +Pcp-group with orders [ 2, 2, 2, 2, 3 ] +gap> # The next two commands used to trigger errors +gap> NonAbelianTensorSquare(Centre(g)); +Pcp-group with orders [ 8 ] +gap> NonAbelianExteriorSquare(Centre(g)); +Pcp-group with orders [ ] + + +gap> # Check for a bug reported 2012-01-19 by Robert Morse +gap> F := FreeGroup("x","y"); + +gap> x := F.1;; y := F.2;; +gap> G := F/[x^2/y^24, y^24, y^x/y^23]; + +gap> iso := IsomorphismPcGroup(G); +[ x, y ] -> [ f1, f2*f5 ] +gap> iso1 := IsomorphismPcpGroup(Image(iso)); +[ f1, f2, f3, f4, f5 ] -> [ g1, g2, g3, g4, g5 ] +gap> G := Image(iso*iso1); +Pcp-group with orders [ 2, 2, 2, 2, 3 ] +gap> # The next command used to trigger an error +gap> NonAbelianTensorSquare(Image(iso*iso1)); +Pcp-group with orders [ 2, 2, 3, 2, 2, 2, 2 ] + + +gap> # The problem with the previous example is/was that Igs(G) +gap> # is set to a non-standard value: +gap> Igs(G); +[ g1, g2*g5, g3*g4*g5^2, g4*g5, g5 ] +gap> # Unfortunately, it seems that a lot of code that +gap> # really should be using Ngs or Cgs is using Igs incorrectly. +gap> # For example, direct products could return *invalid* embeddings: +gap> D := DirectProduct(G, G); +Pcp-group with orders [ 2, 2, 2, 2, 3, 2, 2, 2, 2, 3 ] +gap> hom:=Embedding(D,1);; +gap> mapi:=MappingGeneratorsImages(hom);; +gap> GroupHomomorphismByImages(Source(hom),Range(hom),mapi[1],mapi[2]) <> fail; +true +gap> hom:=Projection(D,1);; +gap> mapi:=MappingGeneratorsImages(hom);; +gap> GroupHomomorphismByImages(Source(hom),Range(hom),mapi[1],mapi[2]) <> fail; +true + + +gap> # Check for bug computing Schur extension of infinite cyclic groups, +gap> # found by Max Horn 2012-05-25 +gap> G:=AbelianPcpGroup(1,[0]); +Pcp-group with orders [ 0 ] +gap> # The next command used to trigger an error +gap> SchurExtension(G); +Pcp-group with orders [ 0 ] + + +gap> # Check for bug computing Schur extensions of subgroups, found by MH 2012-05-25. +gap> G:=HeisenbergPcpGroup(2); +Pcp-group with orders [ 0, 0, 0, 0, 0 ] +gap> H:=Subgroup(G,[G.2^3*G.3^2, G.1^9]); +Pcp-group with orders [ 0, 0, 0 ] +gap> # The next command used to trigger an error +gap> SchurExtension(H); +Pcp-group with orders [ 0, 0, 0, 0, 0, 0 ] + + +gap> # Check for bug computing Schur extensions of subgroups, found by MH 2012-05-25. +gap> G:=HeisenbergPcpGroup(2); +Pcp-group with orders [ 0, 0, 0, 0, 0 ] +gap> H:=Subgroup(G,[G.1, G.2]); +Pcp-group with orders [ 0, 0 ] +gap> # The next command used to trigger an error +gap> SchurExtension(H); +Pcp-group with orders [ 0, 0, 0 ] + + +gap> # Check for bug computing normalizer of two subgroups, found by MH 2012-05-30. +gap> # The problem was caused by incorrect resp. overly restrictive use of Parent(). +gap> G:=HeisenbergPcpGroup(2); +Pcp-group with orders [ 0, 0, 0, 0, 0 ] +gap> A:=Subgroup(Subgroup(G,[G.2,G.3,G.4,G.5]), [G.3]); +Pcp-group with orders [ 0 ] +gap> B:=Subgroup(Subgroup(G,[G.1,G.4,G.5]), [G.4]); +Pcp-group with orders [ 0 ] +gap> Normalizer(A,B); +Pcp-group with orders [ 0 ] +gap> # The following used to trigger the error "arguments must have a common parent group" +gap> Normalizer(B,A); +Pcp-group with orders [ 0 ] + + +gap> # In polycyclic 2.9 and 2.10, the code for 2-cohomology computations was broken. +gap> G := UnitriangularPcpGroup(3,0); +Pcp-group with orders [ 0, 0, 0 ] +gap> mats := G!.mats; +[ [ [ 1, 1, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ], + [ [ 1, 0, 0 ], [ 0, 1, 1 ], [ 0, 0, 1 ] ], + [ [ 1, 0, 1 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ] ] +gap> C := CRRecordByMats(G,mats);; +gap> cc := TwoCohomologyCR(C);; +gap> cc.factor.rels; +[ 2, 0, 0 ] +gap> c := cc.factor.prei[2]; +[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 1 ] +gap> cc.gcb; +[ [ 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0 ], + [ 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1 ], + [ -1, 0, 1, 1, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ], + [ 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1 ] ] +gap> cc.gcc; +[ [ 1, 0, 0, 0, 0, -2, -1, 0, 1, 1, -1, -1, 0, 0, 0, 0, 0, 0 ], + [ 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 1, 0, 0, -2, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 0, 1, 0, 0, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 1 ], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1 ] ] + + +gap> # LowerCentralSeriesOfGroup for non-nilpotent pcp-groups used to trigger +gap> # an infinite recursion +gap> G := PcGroupToPcpGroup(SmallGroup(6,1)); +Pcp-group with orders [ 2, 3 ] +gap> LowerCentralSeriesOfGroup(G); +[ Pcp-group with orders [ 2, 3 ], Pcp-group with orders [ 3 ] ] + + +gap> STOP_TEST( "bugfix.tst", 10000000); diff --git a/samples/GAP/factor.tst b/samples/GAP/factor.tst new file mode 100644 index 00000000..115fe921 --- /dev/null +++ b/samples/GAP/factor.tst @@ -0,0 +1,21 @@ +gap> START_TEST("Test of factor groups and natural homomorphisms"); + +gap> G:=HeisenbergPcpGroup(2); +Pcp-group with orders [ 0, 0, 0, 0, 0 ] + +gap> H:=Subgroup(G,[G.2,G.3,G.4,G.5]); +gap> K:=G/H; +gap> NaturalHomomorphism(K); + +gap> A:=Subgroup(H, [G.3]); +Pcp-group with orders [ 0 ] +gap> B:=Subgroup(Subgroup(G,[G.1,G.4,G.5]), [G.4]); +Pcp-group with orders [ 0 ] +gap> Normalizer(A,B); +Pcp-group with orders [ 0 ] +gap> # The following used to trigger the error "arguments must have a common parent group" +gap> Normalizer(B,A); +Pcp-group with orders [ 0 ] + + +gap> STOP_TEST( "factor.tst", 10000000); diff --git a/samples/GLSL/recurse1.fs b/samples/GLSL/recurse1.fs new file mode 100644 index 00000000..66b4c3fe --- /dev/null +++ b/samples/GLSL/recurse1.fs @@ -0,0 +1,48 @@ +#version 330 core + +// cross-unit recursion + +void main() {} + +// two-level recursion + +float cbar(int); + +void cfoo(float) +{ + cbar(2); +} + +// four-level, out of order + +void CB(); +void CD(); +void CA() { CB(); } +void CC() { CD(); } + +// high degree + +void CBT(); +void CDT(); +void CAT() { CBT(); CBT(); CBT(); } +void CCT() { CDT(); CDT(); CBT(); } + +// not recursive + +void norA() {} +void norB() { norA(); } +void norC() { norA(); } +void norD() { norA(); } +void norE() { norB(); } +void norF() { norB(); } +void norG() { norE(); } +void norH() { norE(); } +void norI() { norE(); } + +// not recursive, but with a call leading into a cycle if ignoring direction + +void norcA() { } +void norcB() { norcA(); } +void norcC() { norcB(); } +void norcD() { norcC(); norcB(); } // head of cycle +void norcE() { norcD(); } // lead into cycle diff --git a/samples/Gosu/Ronin.gs b/samples/Gosu/Ronin.gs new file mode 100644 index 00000000..dfbdee7b --- /dev/null +++ b/samples/Gosu/Ronin.gs @@ -0,0 +1,238 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + +package ronin + +uses gw.util.concurrent.LockingLazyVar +uses gw.lang.reflect.* +uses java.lang.* +uses java.io.* +uses ronin.config.* +uses org.slf4j.* + +/** + * The central location for Ronin utility methods. Controllers and templates should generally access the + * methods and properties they inherit from {@link ronin.IRoninUtils} instead of using the methods and + * properties here. + */ +class Ronin { + + // One static field to rule the all... + static var _CONFIG : IRoninConfig as Config + + // And one thread local to bind them + static var _CURRENT_REQUEST = new ThreadLocal(); + + // That's inconstructable + private construct() {} + + internal static function init(servlet : RoninServlet, m : ApplicationMode, src : File) { + if(_CONFIG != null) { + throw "Cannot initialize a Ronin application multiple times!" + } + var cfg = TypeSystem.getByFullNameIfValid("config.RoninConfig") + var defaultWarning = false + if(cfg != null) { + var ctor = cfg.TypeInfo.getConstructor({ronin.config.ApplicationMode, ronin.RoninServlet}) + if(ctor == null) { + throw "config.RoninConfig must have a constructor with the same signature as ronin.config.RoninConfig" + } + _CONFIG = ctor.Constructor.newInstance({m, servlet}) as IRoninConfig + } else { + _CONFIG = new DefaultRoninConfig(m, servlet) + defaultWarning = true + } + var roninLogger = TypeSystem.getByFullNameIfValid("ronin.RoninLoggerFactory") + if(roninLogger != null) { + roninLogger.TypeInfo.getMethod("init", {ronin.config.LogLevel}).CallHandler.handleCall(null, {LogLevel}) + } + if(defaultWarning) { + log("No configuration was found at config.RoninConfig, using the default configuration...", :level=WARN) + } + Quartz.maybeStart() + ReloadManager.setSourceRoot(src) + } + + internal static property set CurrentRequest(req : RoninRequest) { + _CURRENT_REQUEST.set(req) + } + + //============================================ + // Public API + //============================================ + + /** + * The trace handler for the current request. + */ + static property get CurrentTrace() : Trace { + return CurrentRequest?.Trace + } + + /** + * Ronin's representation of the current request. + */ + static property get CurrentRequest() : RoninRequest { + return _CURRENT_REQUEST.get() + } + + /** + * The mode in which this application is running. + */ + static property get Mode() : ApplicationMode { + return _CONFIG?.Mode ?: TESTING + } + + /** + * The log level at and above which log messages should be displayed. + */ + static property get LogLevel() : LogLevel { + return _CONFIG?.LogLevel ?: DEBUG + } + + /** + * Whether or not to display detailed trace information on each request. + */ + static property get TraceEnabled() : boolean { + return _CONFIG != null ? _CONFIG.TraceEnabled : true + } + + /** + * The default controller method to call when no method name is present in the request URL. + */ + static property get DefaultAction() : String { + return _CONFIG?.DefaultAction + } + + /** + * The default controller to call when no controller name is present in the request URL. + */ + static property get DefaultController() : Type { + return _CONFIG?.DefaultController + } + + /** + * The servlet responsible for handling Ronin requests. + */ + static property get RoninServlet() : RoninServlet { + return _CONFIG?.RoninServlet + } + + /** + * The handler for request processing errors. + */ + static property get ErrorHandler() : IErrorHandler { + return _CONFIG?.ErrorHandler + } + + /** + * The custom handler for logging messages. + */ + static property get LogHandler() : ILogHandler { + return _CONFIG?.LogHandler + } + + /** + * Logs a message using the configured log handler. + * @param msg The text of the message to log, or a block which returns said text. + * @param level (Optional) The level at which to log the message. + * @param component (Optional) The logical component from whence the message originated. + * @param exception (Optional) An exception to associate with the message. + */ + static function log(msg : Object, level : LogLevel = null, component : String = null, exception : java.lang.Throwable = null) { + if(level == null) { + level = INFO + } + if(LogLevel <= level) { + var msgStr : String + if(msg typeis block():String) { + msgStr = (msg as block():String)() + } else { + msgStr = msg as String + } + if(_CONFIG?.LogHandler != null) { + _CONFIG.LogHandler.log(msgStr, level, component, exception) + } else { + switch(level) { + case TRACE: + LoggerFactory.getLogger(component?:Logger.ROOT_LOGGER_NAME).trace(msgStr, exception) + break + case DEBUG: + LoggerFactory.getLogger(component?:Logger.ROOT_LOGGER_NAME).debug(msgStr, exception) + break + case INFO: + LoggerFactory.getLogger(component?:Logger.ROOT_LOGGER_NAME).info(msgStr, exception) + break + case WARN: + LoggerFactory.getLogger(component?:Logger.ROOT_LOGGER_NAME).warn(msgStr, exception) + break + case ERROR: + case FATAL: + LoggerFactory.getLogger(component?:Logger.ROOT_LOGGER_NAME).error(msgStr, exception) + break + } + } + } + } + + /** + * The caches known to Ronin. + */ + static enum CacheStore { + REQUEST, + SESSION, + APPLICATION + } + + /** + * Retrieves a value from a cache, or computes and stores it if it is not in the cache. + * @param value A block which will compute the desired value. + * @param name (Optional) A unique identifier for the value. Default is null, which means one will be + * generated from the type of the value. + * @param store (Optional) The cache store used to retrieve or store the value. Default is the request cache. + * @return The retrieved or computed value. + */ + static function cache(value : block():T, name : String = null, store : CacheStore = null) : T { + if(store == null or store == REQUEST) { + return _CONFIG.RequestCache.getValue(value, name) + } else if (store == SESSION) { + return _CONFIG.SessionCache.getValue(value, name) + } else if (store == APPLICATION) { + return _CONFIG.ApplicationCache.getValue(value, name) + } else { + throw "Don't know about CacheStore ${store}" + } + } + + /** + * Invalidates a cached value in a cache. + * @param name The unique identifier for the value. + * @param store The cache store in which to invalidate the value. + */ + static function invalidate(name : String, store : CacheStore) { + if(store == null or store == REQUEST) { + _CONFIG.RequestCache.invalidate(name) + } else if (store == SESSION) { + _CONFIG.SessionCache.invalidate(name) + } else if (store == APPLICATION) { + _CONFIG.ApplicationCache.invalidate(name) + } else { + throw "Don't know about CacheStore ${store}" + } + } + + + /** + * Detects changes made to resources in the Ronin application and + * reloads them. This function should only be called when Ronin is + * in development mode. + */ + static function loadChanges() { + ReloadManager.detectAndReloadChangedResources() + } + +} diff --git a/samples/Gradle/build.gradle b/samples/Gradle/build.gradle new file mode 100644 index 00000000..190eb3f6 --- /dev/null +++ b/samples/Gradle/build.gradle @@ -0,0 +1,18 @@ +apply plugin: GreetingPlugin + +greeting.message = 'Hi from Gradle' + +class GreetingPlugin implements Plugin { + void apply(Project project) { + // Add the 'greeting' extension object + project.extensions.create("greeting", GreetingPluginExtension) + // Add a task that uses the configuration + project.task('hello') << { + println project.greeting.message + } + } +} + +class GreetingPluginExtension { + def String message = 'Hello from GreetingPlugin' +} diff --git a/samples/Gradle/builder.gradle b/samples/Gradle/builder.gradle new file mode 100644 index 00000000..342be2fd --- /dev/null +++ b/samples/Gradle/builder.gradle @@ -0,0 +1,20 @@ +apply plugin: GreetingPlugin + +greeting { + message = 'Hi' + greeter = 'Gradle' +} + +class GreetingPlugin implements Plugin { + void apply(Project project) { + project.extensions.create("greeting", GreetingPluginExtension) + project.task('hello') << { + println "${project.greeting.message} from ${project.greeting.greeter}" + } + } +} + +class GreetingPluginExtension { + String message + String greeter +} diff --git a/samples/HTML/index.html.hl b/samples/HTML/index.html.hl new file mode 100644 index 00000000..65491957 --- /dev/null +++ b/samples/HTML/index.html.hl @@ -0,0 +1,328 @@ + + + + + + + + +
+

Example 1

+ + + + + +
+ + +
+ +

~{x}

+
+
+
+
+ + +
+

Example 2

+ + + + + +
+ + +
+ +

~{x}

+
+
+
+
+ + +
+

Example 3

+ + + + + +
+ + + +
+ +

~{x}

+
+
+
+
+ + +
+

Example 4

+ + + + + +
+ + +
+
+
+ + +
+

Example 5

+ + + + + +
+ + +
+
+
+ + +
+

Example 6

+ + + + + +
+ + +
+
+ +

~{x}

+
+
+
+
+
+ + +
+

Example 7

+ + + + + +
+ + +
+
+ +

~{x}

+
+
+
+
+
+ + +
+

Example 8

+ + + + + +
+ + +
+
+ +

~{x}

+
+
+
+
+
+ + +
+

Example 9

+ + + + + +
+ + +
+
+ + +
+

Example 10

+ + + + + +
+ + + +
+
+ + diff --git a/samples/Inno Setup/expat.iss b/samples/Inno Setup/expat.iss new file mode 100644 index 00000000..4ccdbf2c --- /dev/null +++ b/samples/Inno Setup/expat.iss @@ -0,0 +1,69 @@ +; Basic setup script for the Inno Setup installer builder. For more +; information on the free installer builder, see www.jrsoftware.org. +; +; This script was contributed by Tim Peters. +; It was designed for Inno Setup 2.0.19 but works with later versions as well. + +[Setup] +AppName=Expat +AppId=expat +AppVersion=2.1.0 +AppVerName=Expat 2.1.0 +AppCopyright=Copyright 1998-2012 Thai Open Source Software Center, Clark Cooper, and the Expat maintainers +AppPublisher=The Expat Developers +AppPublisherURL=http://www.libexpat.org/ +AppSupportURL=http://www.libexpat.org/ +AppUpdatesURL=http://www.libexpat.org/ +UninstallDisplayName=Expat XML Parser 2.1.0 +VersionInfoVersion=2.1.0 + +DefaultDirName={pf}\Expat 2.1.0 +UninstallFilesDir={app}\Uninstall + +Compression=lzma +SolidCompression=yes +SourceDir=.. +OutputDir=win32 +DisableStartupPrompt=yes +AllowNoIcons=yes +DisableProgramGroupPage=yes +DisableReadyPage=yes + +[Files] +Flags: ignoreversion; Source: win32\bin\Release\xmlwf.exe; DestDir: "{app}\Bin" +Flags: ignoreversion; Source: win32\MANIFEST.txt; DestDir: "{app}" +Flags: ignoreversion; Source: Changes; DestDir: "{app}"; DestName: Changes.txt +Flags: ignoreversion; Source: COPYING; DestDir: "{app}"; DestName: COPYING.txt +Flags: ignoreversion; Source: README; DestDir: "{app}"; DestName: README.txt +Flags: ignoreversion; Source: doc\*.html; DestDir: "{app}\Doc" +Flags: ignoreversion; Source: doc\*.css; DestDir: "{app}\Doc" +Flags: ignoreversion; Source: doc\*.png; DestDir: "{app}\Doc" +Flags: ignoreversion; Source: win32\bin\Release\*.dll; DestDir: "{app}\Bin" +Flags: ignoreversion; Source: win32\bin\Release\*.lib; DestDir: "{app}\Bin" +Flags: ignoreversion; Source: expat.dsw; DestDir: "{app}\Source" +Flags: ignoreversion; Source: win32\README.txt; DestDir: "{app}\Source" +Flags: ignoreversion; Source: bcb5\*.bp*; DestDir: "{app}\Source\bcb5" +Flags: ignoreversion; Source: bcb5\*.mak; DestDir: "{app}\Source\bcb5" +Flags: ignoreversion; Source: bcb5\*.def; DestDir: "{app}\Source\bcb5" +Flags: ignoreversion; Source: bcb5\*.txt; DestDir: "{app}\Source\bcb5" +Flags: ignoreversion; Source: bcb5\*.bat; DestDir: "{app}\Source\bcb5" +Flags: ignoreversion; Source: lib\*.c; DestDir: "{app}\Source\lib" +Flags: ignoreversion; Source: lib\*.h; DestDir: "{app}\Source\lib" +Flags: ignoreversion; Source: lib\*.def; DestDir: "{app}\Source\lib" +Flags: ignoreversion; Source: lib\*.dsp; DestDir: "{app}\Source\lib" +Flags: ignoreversion; Source: examples\*.c; DestDir: "{app}\Source\examples" +Flags: ignoreversion; Source: examples\*.dsp; DestDir: "{app}\Source\examples" +Flags: ignoreversion; Source: tests\*.c; DestDir: "{app}\Source\tests" +Flags: ignoreversion; Source: tests\*.cpp; DestDir: "{app}\Source\tests" +Flags: ignoreversion; Source: tests\*.h; DestDir: "{app}\Source\tests" +Flags: ignoreversion; Source: tests\README.txt; DestDir: "{app}\Source\tests" +Flags: ignoreversion; Source: tests\benchmark\*.c; DestDir: "{app}\Source\tests\benchmark" +Flags: ignoreversion; Source: tests\benchmark\*.ds*; DestDir: "{app}\Source\tests\benchmark" +Flags: ignoreversion; Source: tests\benchmark\README.txt; DestDir: "{app}\Source\tests\benchmark" +Flags: ignoreversion; Source: xmlwf\*.c*; DestDir: "{app}\Source\xmlwf" +Flags: ignoreversion; Source: xmlwf\*.h; DestDir: "{app}\Source\xmlwf" +Flags: ignoreversion; Source: xmlwf\*.dsp; DestDir: "{app}\Source\xmlwf" + +[Messages] +WelcomeLabel1=Welcome to the Expat XML Parser Setup Wizard +WelcomeLabel2=This will install [name/ver] on your computer.%n%nExpat is an XML parser with a C-language API, and is primarily made available to allow developers to build applications which use XML using a portable API and fast implementation.%n%nIt is strongly recommended that you close all other applications you have running before continuing. This will help prevent any conflicts during the installation process. diff --git a/samples/J/stwij.ijs b/samples/J/stwij.ijs new file mode 100644 index 00000000..453af90b --- /dev/null +++ b/samples/J/stwij.ijs @@ -0,0 +1,73 @@ +NB. From "Continuing to write in J". +NB. See http://www.jsoftware.com/help/jforc/continuing_to_write_in_j.htm + +empno=: 316 317 319 320 +payrate=: 60 42 44 54 +billrate=: 120 90 90 108 +clientlist=: 10011 10012 10025 +emp_client=: 10012 10025 10012 10025 +hoursworked=: 4 31 $ 8 0 3 10 9 8 8 9 4 0 8 7 10 10 12 9 0 6 8 9 9 9 0 0 10 11 9 7 10 2 0 8 0 0 9 9 8 9 10 0 0 8 8 10 7 10 0 0 7 8 9 8 9 0 4 9 8 9 8 9 0 0 5 0 0 8 9 9 9 9 0 0 8 7 0 0 9 0 2 10 10 9 11 8 0 0 8 9 10 8 9 0 0 9 0 0 9 10 8 6 6 8 0 9 8 10 6 9 7 0 6 8 8 8 9 0 5 8 9 8 8 12 0 0 + +NB. Finds the number of hours each employee worked in the given month. +emphours=: 3 : '+/"1 hoursworked' + +NB. Determines the wages earned by each employee in the given month. +empearnings=: 3 : 'payrate * +/"1 hoursworked' + +NB. Determines the profit brought in by each employee. +empprofit=: 3 : 0 +(billrate - payrate) * +/"1 hoursworked +) + +NB. Returns the amount to bill a given client. +billclient=: 3 : 0 +mask=. emp_client = y ++/ (mask # billrate) * +/"1 mask # hoursworked +) + +NB. Finds for each day of the month the employee who billed the most hours. +dailydrudge=: 3 : 0 +((|: hoursworked) i."1 0 >./ hoursworked) { empno +) + +NB. Returns the employees, in descending order of the profit brought in by each. +producers=: 3 : 'empno \: empprofit 0' + +NB. Returns the clients, in descending order of the profit generated by each. +custbyprofit=: 3 : 0 +clientlist \: +/ (clientlist ="1 0 emp_client) * empprofit 0 +) + +NB. Calculates withholding tax on each employee's earnings. +renderuntocaesar=: 3 : 0 +bktmin=. 0 6000 10000 20000 NB. Four brackets, 0..6000..10000..20000.._ +bktrate=. 0.05 0.10 0.20 0.30 +bktearns=. 0 >. ((1 |.!._ bktmin) <."1 0 empearnings'') -"1 bktmin ++/"1 bktrate *"1 bktearns +) + +NB. Main + +echo 'Problem 1' +echo emphours'' + +echo 'Problem 2' +echo empearnings'' + +echo 'Problem 3' +echo empprofit'' + +echo 'Problem 4' +echo billclient 10025 + +echo 'Problem 5' +echo dailydrudge'' + +echo 'Problem 6' +echo producers'' + +echo 'Problem 7' +echo custbyprofit'' + +echo 'Problem 8' +echo 0j2 ": renderuntocaesar'' diff --git a/samples/Jasmin/if1.j b/samples/Jasmin/if1.j new file mode 100644 index 00000000..dc46a541 --- /dev/null +++ b/samples/Jasmin/if1.j @@ -0,0 +1,56 @@ +.class public if1 +.super java/lang/Object +; +; standard initializer (calls java.lang.Object's initializer) +; +.method public ()V +aload_0 +invokenonvirtual java/lang/Object/()V +return +.end method + +.method public static main([Ljava/lang/String;)V + +.limit locals 1 +.limit stack 5 +BeginGlobal: + .line 2 + ldc 0x1 + ldc 0x1 + if_icmpeq If556261059 + goto IfElse556261059 + If556261059: + .line 3 + .line 3 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + invokevirtual java/io/PrintStream/print(I)V + goto IfDone556261059 + IfElse556261059: + .line 5 + .line 5 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x2 + invokevirtual java/io/PrintStream/print(I)V + IfDone556261059: + + .line 6 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x3 + invokevirtual java/io/PrintStream/print(I)V + + .line 7 + ldc 0x1 + ldc 0x1 + if_icmpne IfNot-920218690 + .line 8 + .line 8 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x4 + invokevirtual java/io/PrintStream/print(I)V + IfNot-920218690: + +EndGlobal: +return +.end method + diff --git a/samples/Jasmin/if2.j b/samples/Jasmin/if2.j new file mode 100644 index 00000000..e6121c18 --- /dev/null +++ b/samples/Jasmin/if2.j @@ -0,0 +1,167 @@ +.class public if2 +.super java/lang/Object +; +; standard initializer (calls java.lang.Object's initializer) +; +.method public ()V +aload_0 +invokenonvirtual java/lang/Object/()V +return +.end method + +.method public static main([Ljava/lang/String;)V + +.limit locals 1 +.limit stack 5 +BeginGlobal: + .line 2 + ldc 0x1 + ldc 0x1 + if_icmpeq Cmp1893841232 + ldc 0x0 + goto CmpDone1893841232 + Cmp1893841232: + ldc 0x1 + CmpDone1893841232: + ldc 0x1 + if_icmpeq If-1736765035 + goto IfElse-1736765035 + If-1736765035: + .line 2 + .line 3 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + invokevirtual java/io/PrintStream/print(I)V + goto IfDone-1736765035 + IfElse-1736765035: + .line 4 + .line 4 + ldc 0x2 + ldc 0x1 + if_icmpeq Cmp-1460884369 + ldc 0x0 + goto CmpDone-1460884369 + Cmp-1460884369: + ldc 0x1 + CmpDone-1460884369: + ldc 0x1 + if_icmpeq If-247349760 + goto IfElse-247349760 + If-247349760: + .line 4 + .line 5 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x2 + invokevirtual java/io/PrintStream/print(I)V + goto IfDone-247349760 + IfElse-247349760: + .line 6 + .line 7 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x3 + invokevirtual java/io/PrintStream/print(I)V + IfDone-247349760: + IfDone-1736765035: + + .line 10 + ldc 0x1 + ldc 0x2 + if_icmpeq Cmp933554851 + ldc 0x0 + goto CmpDone933554851 + Cmp933554851: + ldc 0x1 + CmpDone933554851: + ldc 0x1 + if_icmpeq If1623625546 + goto IfElse1623625546 + If1623625546: + .line 10 + .line 11 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + invokevirtual java/io/PrintStream/print(I)V + goto IfDone1623625546 + IfElse1623625546: + .line 12 + .line 12 + ldc 0x2 + ldc 0x2 + if_icmpeq Cmp1572138409 + ldc 0x0 + goto CmpDone1572138409 + Cmp1572138409: + ldc 0x1 + CmpDone1572138409: + ldc 0x1 + if_icmpeq If126354425 + goto IfElse126354425 + If126354425: + .line 12 + .line 13 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x2 + invokevirtual java/io/PrintStream/print(I)V + goto IfDone126354425 + IfElse126354425: + .line 14 + .line 15 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x3 + invokevirtual java/io/PrintStream/print(I)V + IfDone126354425: + IfDone1623625546: + + .line 18 + ldc 0x1 + ldc 0x2 + if_icmpeq Cmp126493150 + ldc 0x0 + goto CmpDone126493150 + Cmp126493150: + ldc 0x1 + CmpDone126493150: + ldc 0x1 + if_icmpeq If1522284422 + goto IfElse1522284422 + If1522284422: + .line 18 + .line 19 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + invokevirtual java/io/PrintStream/print(I)V + goto IfDone1522284422 + IfElse1522284422: + .line 20 + .line 20 + ldc 0x2 + ldc 0x1 + if_icmpeq Cmp-906666545 + ldc 0x0 + goto CmpDone-906666545 + Cmp-906666545: + ldc 0x1 + CmpDone-906666545: + ldc 0x1 + if_icmpeq If1083939031 + goto IfElse1083939031 + If1083939031: + .line 20 + .line 21 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x2 + invokevirtual java/io/PrintStream/print(I)V + goto IfDone1083939031 + IfElse1083939031: + .line 22 + .line 23 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x3 + invokevirtual java/io/PrintStream/print(I)V + IfDone1083939031: + IfDone1522284422: + +EndGlobal: +return +.end method + diff --git a/samples/Jasmin/if3.j b/samples/Jasmin/if3.j new file mode 100644 index 00000000..3d687392 --- /dev/null +++ b/samples/Jasmin/if3.j @@ -0,0 +1,55 @@ +.class public if3 +.super java/lang/Object +; +; standard initializer (calls java.lang.Object's initializer) +; +.method public ()V +aload_0 +invokenonvirtual java/lang/Object/()V +return +.end method + +.method public static main([Ljava/lang/String;)V + +.limit locals 1 +.limit stack 5 +BeginGlobal: + .line 2 + ldc 0x1 + ldc 0x1 + if_icmpeq If-811796083 + goto IfElse-811796083 + If-811796083: + .line 3 + .line 3 + ldc 0x0 + ldc 0x1 + if_icmpeq If-1001319390 + goto IfElse-1001319390 + If-1001319390: + .line 4 + .line 4 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + invokevirtual java/io/PrintStream/print(I)V + goto IfDone-1001319390 + IfElse-1001319390: + .line 6 + .line 6 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x2 + invokevirtual java/io/PrintStream/print(I)V + IfDone-1001319390: + goto IfDone-811796083 + IfElse-811796083: + .line 8 + .line 8 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x3 + invokevirtual java/io/PrintStream/print(I)V + IfDone-811796083: + +EndGlobal: +return +.end method + diff --git a/samples/Jasmin/if4.j b/samples/Jasmin/if4.j new file mode 100644 index 00000000..f79a090b --- /dev/null +++ b/samples/Jasmin/if4.j @@ -0,0 +1,37 @@ +.class public if4 +.super java/lang/Object +; +; standard initializer (calls java.lang.Object's initializer) +; +.method public ()V +aload_0 +invokenonvirtual java/lang/Object/()V +return +.end method + +.method public static main([Ljava/lang/String;)V + +.limit locals 1 +.limit stack 5 +BeginGlobal: + .line 2 + ldc 0x1 + ldc 0x1 + if_icmpne IfNot1919266740 + .line 2 + .line 2 + ldc 0x1 + ldc 0x1 + if_icmpne IfNot613368541 + .line 2 + .line 2 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + invokevirtual java/io/PrintStream/print(I)V + IfNot613368541: + IfNot1919266740: + +EndGlobal: +return +.end method + diff --git a/samples/Jasmin/op1.j b/samples/Jasmin/op1.j new file mode 100644 index 00000000..d8344913 --- /dev/null +++ b/samples/Jasmin/op1.j @@ -0,0 +1,54 @@ +.class public op1 +.super java/lang/Object +; +; standard initializer (calls java.lang.Object's initializer) +; +.method public ()V +aload_0 +invokenonvirtual java/lang/Object/()V +return +.end method + +.method public static main([Ljava/lang/String;)V + +.limit locals 1 +.limit stack 5 +BeginGlobal: + .line 2 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + ldc 0x1 + iadd + invokevirtual java/io/PrintStream/println(I)V + + .line 3 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0xa + ldc 0x5 + isub + invokevirtual java/io/PrintStream/println(I)V + + .line 4 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x15 + ldc 0x3 + idiv + invokevirtual java/io/PrintStream/println(I)V + + .line 5 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x159 + ldc 0x38 + imul + invokevirtual java/io/PrintStream/println(I)V + + .line 6 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x52 + ldc 0x9 + irem + invokevirtual java/io/PrintStream/println(I)V + +EndGlobal: +return +.end method \ No newline at end of file diff --git a/samples/Jasmin/op2.j b/samples/Jasmin/op2.j new file mode 100644 index 00000000..4463a5ca --- /dev/null +++ b/samples/Jasmin/op2.j @@ -0,0 +1,34 @@ +.class public op2 +.super java/lang/Object +; +; standard initializer (calls java.lang.Object's initializer) +; +.method public ()V +aload_0 +invokenonvirtual java/lang/Object/()V +return +.end method + +.method public static main([Ljava/lang/String;)V + +.limit locals 1 +.limit stack 5 +BeginGlobal: + .line 2 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + ldc 0x0 + iand + invokevirtual java/io/PrintStream/println(Z)V + + .line 3 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + ldc 0x0 + ior + invokevirtual java/io/PrintStream/println(Z)V + +EndGlobal: +return +.end method + diff --git a/samples/Jasmin/op3.j b/samples/Jasmin/op3.j new file mode 100644 index 00000000..10dd6897 --- /dev/null +++ b/samples/Jasmin/op3.j @@ -0,0 +1,68 @@ +.class public op3 +.super java/lang/Object +; +; standard initializer (calls java.lang.Object's initializer) +; +.method public ()V +aload_0 +invokenonvirtual java/lang/Object/()V +return +.end method + +.method public static main([Ljava/lang/String;)V + +.limit locals 1 +.limit stack 5 +BeginGlobal: + .line 2 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x0 + ldc 0x1 + if_icmpeq Cmp-1307183590 + ldc 0x0 + goto CmpDone-1307183590 + Cmp-1307183590: + ldc 0x1 + CmpDone-1307183590: + invokevirtual java/io/PrintStream/println(Z)V + + .line 3 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x0 + ldc 0x0 + if_icmpeq Cmp-1443270821 + ldc 0x0 + goto CmpDone-1443270821 + Cmp-1443270821: + ldc 0x1 + CmpDone-1443270821: + invokevirtual java/io/PrintStream/println(Z)V + + .line 4 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + ldc 0x1 + if_icmpeq Cmp1759327329 + ldc 0x0 + goto CmpDone1759327329 + Cmp1759327329: + ldc 0x1 + CmpDone1759327329: + invokevirtual java/io/PrintStream/println(Z)V + + .line 5 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + ldc 0x0 + if_icmpeq Cmp-678570146 + ldc 0x0 + goto CmpDone-678570146 + Cmp-678570146: + ldc 0x1 + CmpDone-678570146: + invokevirtual java/io/PrintStream/println(Z)V + +EndGlobal: +return +.end method + diff --git a/samples/Jasmin/op4.j b/samples/Jasmin/op4.j new file mode 100644 index 00000000..47644392 --- /dev/null +++ b/samples/Jasmin/op4.j @@ -0,0 +1,68 @@ +.class public op4 +.super java/lang/Object +; +; standard initializer (calls java.lang.Object's initializer) +; +.method public ()V +aload_0 +invokenonvirtual java/lang/Object/()V +return +.end method + +.method public static main([Ljava/lang/String;)V + +.limit locals 1 +.limit stack 5 +BeginGlobal: + .line 2 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x0 + ldc 0x1 + if_icmpne Cmp-191731100 + ldc 0x0 + goto CmpDone-191731100 + Cmp-191731100: + ldc 0x1 + CmpDone-191731100: + invokevirtual java/io/PrintStream/println(Z)V + + .line 3 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x0 + ldc 0x0 + if_icmpne Cmp-901585603 + ldc 0x0 + goto CmpDone-901585603 + Cmp-901585603: + ldc 0x1 + CmpDone-901585603: + invokevirtual java/io/PrintStream/println(Z)V + + .line 4 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + ldc 0x1 + if_icmpne Cmp1522577937 + ldc 0x0 + goto CmpDone1522577937 + Cmp1522577937: + ldc 0x1 + CmpDone1522577937: + invokevirtual java/io/PrintStream/println(Z)V + + .line 5 + getstatic java/lang/System/out Ljava/io/PrintStream; + ldc 0x1 + ldc 0x0 + if_icmpne Cmp-1653028684 + ldc 0x0 + goto CmpDone-1653028684 + Cmp-1653028684: + ldc 0x1 + CmpDone-1653028684: + invokevirtual java/io/PrintStream/println(Z)V + +EndGlobal: +return +.end method + diff --git a/samples/JavaScript/chart_composers.gs b/samples/JavaScript/chart_composers.gs new file mode 100644 index 00000000..3b6f4400 --- /dev/null +++ b/samples/JavaScript/chart_composers.gs @@ -0,0 +1,78 @@ +/* +License +Copyright [2013] [Farruco Sanjurjo Arcay] + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +*/ + +var TagsTotalPerMonth; + +TagsTotalPerMonth = (function(){ + function TagsTotalPerMonth(){}; + + TagsTotalPerMonth.getDatasource = function (category, months, values){ + return new CategoryMonthlyExpenseBarChartDataSource(category, months, values); + }; + + TagsTotalPerMonth.getType = function (){ return Charts.ChartType.COLUMN}; + + return TagsTotalPerMonth; +})(); + + +var TagsTotalPerMonthWithMean; + +TagsTotalPerMonthWithMean = (function(){ + function TagsTotalPerMonthWithMean(){}; + + TagsTotalPerMonthWithMean.getDatasource = function (category, months, values){ + return new CategoryMonthlyWithMeanExpenseDataSource(category, months, values); + }; + + TagsTotalPerMonthWithMean.getType = function (){ return Charts.ChartType.LINE}; + + return TagsTotalPerMonthWithMean; +})(); + + +var TagsAccumulatedPerMonth; + +TagsAccumulatedPerMonth = (function(){ + function TagsAccumulatedPerMonth(){}; + + TagsAccumulatedPerMonth.getDatasource = function (category, months, values){ + return new CategoryMonthlyAccumulated(category, months, values); + }; + + TagsAccumulatedPerMonth.getType = function (){ return Charts.ChartType.AREA}; + + return TagsAccumulatedPerMonth; +})(); + +var MonthTotalsPerTags; + +MonthTotalsPerTags = (function(){ + function MonthTotalsPerTags(){}; + + MonthTotalsPerTags.getDatasource = function (month, tags, values){ + return new CategoryExpenseDataSource(tags, month, values); + }; + + MonthTotalsPerTags.getType = function (){ return Charts.ChartType.PIE; }; + + return MonthTotalsPerTags; +})(); + +var SavingsFlowChartComposer = (function(){ + function SavingsFlowChartComposer(){}; + + SavingsFlowChartComposer.getDatasource = function(months, values){ + return new SavingsFlowDataSource(months, values); + }; + + SavingsFlowChartComposer.getType = function(){ return Charts.ChartType.COLUMN; }; + + return SavingsFlowChartComposer; +})(); diff --git a/samples/JavaScript/itau.gs b/samples/JavaScript/itau.gs new file mode 100644 index 00000000..d745a3fb --- /dev/null +++ b/samples/JavaScript/itau.gs @@ -0,0 +1,150 @@ +/* +The MIT License (MIT) + +Copyright (c) 2014 Thiago Brandão Damasceno + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +// based on http://ctrlq.org/code/19053-send-to-google-drive +function sendToGoogleDrive() { + + var gmailLabels = 'inbox'; + var driveFolder = 'Itaú Notifications'; + var spreadsheetName = 'itau'; + var archiveLabel = 'itau.processed'; + var itauNotificationEmail = 'comunicacaodigital@itau-unibanco.com.br'; + var filter = "from: " + + itauNotificationEmail + + " -label:" + + archiveLabel + + " label:" + + gmailLabels; + + // Create label for 'itau.processed' if it doesn't exist + var moveToLabel = GmailApp.getUserLabelByName(archiveLabel); + + if (!moveToLabel) { + moveToLabel = GmailApp.createLabel(archiveLabel); + } + + // Create folder 'Itaú Notifications' if it doesn't exist + var folders = DriveApp.getFoldersByName(driveFolder); + var folder; + + if (folders.hasNext()) { + folder = folders.next(); + } else { + folder = DriveApp.createFolder(driveFolder); + } + + // Create spreadsheet file 'itau' if it doesn't exist + var files = folder.getFilesByName(spreadsheetName); + + // File is in DriveApp + // Doc is in SpreadsheetApp + // They are not interchangeable + var file, doc; + + // Confusing :\ + // As per: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3578 + if (files.hasNext()){ + file = files.next(); + doc = SpreadsheetApp.openById(file.getId()); + } else { + doc = SpreadsheetApp.create(spreadsheetName); + file = DriveApp.getFileById(doc.getId()); + folder.addFile(file); + DriveApp.removeFile(file); + } + + var sheet = doc.getSheets()[0]; + + // Append header if first line + if(sheet.getLastRow() == 0){ + sheet.appendRow(['Conta', 'Operação', 'Valor', 'Data', 'Hora', 'Email ID']); + } + + var message, messages, account, operation, value, date, hour, emailID, plainBody; + var accountRegex = /Conta: (XXX[0-9\-]+)/; + var operationRegex = /Tipo de operação: ([A-Z]+)/; + var paymentRegex = /Pagamento de ([0-9A-Za-z\-]+)\ ?([0-9]+)?/; + var valueRegex = /Valor: R\$ ([0-9\,\.]+)/; + var dateRegex = /Data: ([0-9\/]+)/; + var hourRegex = /Hora: ([0-9\:]+)/; + var emailIDRegex = /E-mail nº ([0-9]+)/; + + var threads = GmailApp.search(filter, 0, 100); + + for (var x = 0; x < threads.length; x++) { + messages = threads[x].getMessages(); + + for (var i = 0; i < messages.length; i++) { + account, operation, value, date, hour, emailID = []; + + message = messages[i]; + + plainBody = message.getPlainBody(); + + if(accountRegex.test(plainBody)) { + account = RegExp.$1; + } + + if(operationRegex.test(plainBody)) { + operation = RegExp.$1; + } + + if(valueRegex.test(plainBody)) { + value = RegExp.$1; + } + + if(dateRegex.test(plainBody)) { + date = RegExp.$1; + } + + if(hourRegex.test(plainBody)) { + hour = RegExp.$1; + } + + if(emailIDRegex.test(plainBody)){ + emailID = RegExp.$1; + } + + if(paymentRegex.test(plainBody)){ + operation = RegExp.$1; + if(RegExp.$2){ + operation += ' ' + RegExp.$2 + } + date = hour = ' - '; + } + + if(account && operation && value && date && hour){ + sheet.appendRow([account, operation, value, date, hour, emailID]); + } + + // Logger.log(account); + // Logger.log(operation); + // Logger.log(value); + // Logger.log(date); + // Logger.log(hour); + } + + threads[x].addLabel(moveToLabel); + } +} diff --git a/samples/JavaScript/namespace.js b/samples/JavaScript/namespace.js new file mode 100644 index 00000000..26d9acbd --- /dev/null +++ b/samples/JavaScript/namespace.js @@ -0,0 +1,93 @@ +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['lodash'], factory); + } else if (typeof exports !== 'undefined') { + module.exports = factory(require('lodash')); + } else { + root.Namespace = factory(root._); + } +})(this, function(_) { + 'use strict'; + + /** + * @module namespace + * @class namespace + */ + function Namespace() {} + + /** + * Regex for splitting keypaths into arrays. + * + * @private + * @const {RegExp} + * @type + */ + var KEYPATH_SPLITTER = /\./g; + + /** + * An internal cache to avoid calculating a keypath more than once. + * + * @private + * @type {Object} + */ + var _keypaths = {}; + + _.extend(Namespace.prototype, { + + /** + * Adds a definition to the namespace object. + * + * @public + * @instance + * @method add + * @param {String} keypath - The keypath for the definition to be added at. + * @param {Function|Object} definition - The definition to be added. + * @return {Function|Object} - The definition. + */ + add: function(keypath, definition) { + return this._walk(keypath, function(memo, name, index, keypath) { + if (index + 1 === keypath.length) { + memo[name] = _.extend(definition, memo[name]); + } + return memo[name] || (memo[name] = {}); + }); + }, + + /** + * Retrieves a definition from the namespace safely. + * + * @public + * @instance + * @method get + * @param {String} keypath - The keypath to lookup a definition for. + * @returns {Function|Object|undefined} - The definition if it exists, otherwise `undefined`. + */ + get: function(keypath) { + return this._walk(keypath); + }, + + /** + * An internal function for walking a keypath. + * + * @private + * @instance + * @method _walk + * @param {String} keypath - The keypath to walk through. + * @param {Function} [callback] - An optional callback to be called at each item in the path. + * @returns {function|Object|undefined} - The reduced keypath. + */ + _walk: function(keypath, callback) { + return _.reduce( + _keypaths[keypath] || (_keypaths[keypath] = keypath.split(KEYPATH_SPLITTER)), + callback || function(memo, name) { + return memo && memo[name]; + }, + this + ); + } + }); + + return Namespace; +}); + +//# sourceMappingURL=namespace.js.map \ No newline at end of file diff --git a/samples/LoomScript/HelloWorld.ls b/samples/LoomScript/HelloWorld.ls new file mode 100644 index 00000000..d3ba35f7 --- /dev/null +++ b/samples/LoomScript/HelloWorld.ls @@ -0,0 +1,38 @@ +package +{ + import loom.Application; + import loom2d.display.StageScaleMode; + import loom2d.ui.SimpleLabel; + + /** + The HelloWorld app renders a label with its name on it, + and traces 'hello' to the log. + */ + public class HelloWorld extends Application + { + + override public function run():void + { + stage.scaleMode = StageScaleMode.LETTERBOX; + centeredMessage(simpleLabel, this.getFullTypeName()); + + trace("hello"); + } + + // a convenience getter that generates a label and adds it to the stage + private function get simpleLabel():SimpleLabel + { + return stage.addChild(new SimpleLabel("assets/Curse-hd.fnt")) as SimpleLabel; + } + + // a utility to set the label's text and then center it on the stage + private function centeredMessage(label:SimpleLabel, msg:String):void + { + label.text = msg; + label.center(); + label.x = stage.stageWidth / 2; + label.y = (stage.stageHeight / 2) - (label.height / 2); + } + + } +} diff --git a/samples/LoomScript/SyntaxExercise.ls b/samples/LoomScript/SyntaxExercise.ls new file mode 100644 index 00000000..444ee1da --- /dev/null +++ b/samples/LoomScript/SyntaxExercise.ls @@ -0,0 +1,137 @@ +package +{ + import loom.Application; + + public interface I {} + public class C {} + public class B extends C implements I {} + final public class A extends B {} + + delegate ToCompute(s:String, o:Object):Number; + + public enum Enumeration + { + foo, + baz, + cat, + } + + struct P { + public var x:Number = 0; + public var y:Number = 0; + public static operator function =(a:P, b:P):P + { + a.x = b.x; + a.y = b.y; + + return a; + } + } + + // single-line comment + + /* + Multi-line comment + */ + + /** + Doc comment + */ + public class SyntaxExercise extends Application + { + static public var classVar:String = 'class variable'; + public const CONST:String = 'constant'; + private var _a:A = new A(); + public var _d:ToCompute; + + override public function run():void + { + trace("hello"); + } + + private function get a():A { return _a; } + private function set a(value:A):void { _a = value; } + + private function variousTypes(defaultValue:String = ''):void + { + var nil:Object = null; + var b1:Boolean = true; + var b2:Boolean = false; + var n1:Number = 0.123; + var n2:Number = 12345; + var n3:Number = 0xfed; + var s1:String = 'single-quotes with "quotes" inside'; + var s2:String = "double-quotes with 'quotes' inside"; + var f1:Function = function (life:String, universe:Object, ...everything):Number { return 42; }; + var v1:Vector. = [1, 2]; + var d1:Dictionary. = { 'three': 3, 'four': 4 }; + + _d += f1; + _d -= f1; + } + + private function variousOps():void + { + var a = ((100 + 200 - 0) / 300) % 2; + var b = 100 * 30; + var d = true && (b > 301); + var e = 0x10 | 0x01; + + b++; b--; + a += 300; a -= 5; a *= 4; a /= 2; a %= 7; + + var castable1:Boolean = (a is B); + var castable2:Boolean = (a as B) != null; + var cast:String = B(a).toString(); + var instanced:Boolean = (_a instanceof A); + } + + private function variousFlow():void + { + var n:Number = Math.random(); + if (n > 0.6) + trace('top 40!'); + else if(n > 0.3) + trace('mid 30!'); + else + trace('bottom 30'); + + var flip:String = (Math.random() > 0.5) ? 'heads' : 'tails'; + + for (var i = 0; i < 100; i++) + trace(i); + + var v:Vector. = ['a', 'b', 'c']; + for each (var s:String in v) + trace(s); + + var d:Dictionary. = { 'one': 1 }; + for (var key1:String in d) + trace(key1); + + for (var key2:Number in v) + trace(key2); + + while (i > 0) + { + i--; + if (i == 13) continue; + trace(i); + } + + do + { + i++; + } + while (i < 10); + + switch (Math.floor(Math.random()) * 3 + 1) + { + case 1 : trace('rock'); break; + case 2 : trace('paper'); break; + default: trace('scissors'); break; + } + } + + } +} diff --git a/samples/Mathematica/HeyexImport.m b/samples/Mathematica/HeyexImport.m new file mode 100644 index 00000000..457a7e92 --- /dev/null +++ b/samples/Mathematica/HeyexImport.m @@ -0,0 +1,344 @@ +(* Mathematica Package *) +(* Created with IntelliJ IDEA and the Mathematica Language plugin *) + +(* :Title: Importer for the RAW data-format of the Heidelberg Eye Explorer (known as HEYEX) *) + +(* :Context: HeyexImport` *) + +(* :Author: Patrick Scheibe pscheibe@trm.uni-leipzig.de *) + +(* :Package Version: 1.0 *) + +(* :Mathematica Version: 8.0 *) + +(* :Copyright: Patrick Scheibe, 2013-2015 *) + +(* :Discussion: This package registers a new importer which can load the RAW data-format exported by a + Heidelberg Spectralis OCT. The import-functionality can access different information contained + in a file: + 1. The file header which contains meta data like when the patient was scanned etc + 2. The scanned volume data + 3. Images which represent slices of the scanned volume + 4. The Scanning laser ophthalmoscopy (SLO) image which is taken with every scanned patient + 5. The segmentation data for different retina layers provided by the software + +*) + +(* :Keywords: Import, Heyex, OCT, Spectralis, Heidelberg Engineering *) + +BeginPackage[ "HeyexImport`" ] + +HeyexEyePosition::usage = "HeyexEyePosition[file] tries to extract which eye was scanned, left or right."; + +HeyexImport::wrongHdr = "Error importing OCT data. Broken/Wrong file?"; + + +Begin[ "`Private`" ]; + +(* + Registration of all import possibilities for the Heidelberg OCT. +*) + +ImportExport`RegisterImport[ + "Heyex" , + { + "FileHeader" :> importHeader, + { "Data" , n_Integer} :> (importData[n][##]&), + "Data" :> importData, + { "Images" , n_Integer} :> (importImages[n][##]&), + "Images" :> importImages, + "SLOImage" :> importSLOImage, + "SegmentationData" :> importSegmentation, + { "SegmentationData" , n_Integer} :> (importSegmentation[n][##]&), + "DataSize" :> importDataSize, + importData + }, + + { + "Image3D" :> (Image3D["Data" /. #1]&) + }, + + "AvailableElements" -> {"FileHeader", "Data", "DataSize", "Images", "SLOImage", "SegmentationData", "Image3D"} +]; + + +If[Quiet[Check[TrueQ[Compile[{}, 0, CompilationTarget -> "C"][] == 0], False]], + $compileTarget = CompilationTarget -> "C", + $compileTarget = CompilationTarget -> "MVM" +]; + + +(* + Helper function which reads data from a stream. This is + only a unification so I can map the read function over a + list. +*) +read[{id_String, type_String}, str_] := +id -> BinaryRead[str, type]; +read[{type_String, n_Integer}, str_] := BinaryReadList[str, type, n]; +read[{id_String, {type_String, n_Integer}}, str_] := id -> BinaryReadList[str, type, n]; +(* + Note that when reading bytes explicitly I convert them to + a string and remove any zeroes at the end. +*) +read[{id_String, { "Byte" , n_Integer}}, str_] := +id -> StringJoin[ + FromCharacterCode /@ (Rest[ + NestList[BinaryRead[str, "Byte" ] &, Null, + n]] /. {chars___Integer, Longest[0 ...]} :> {chars})]; + +(* + The layout of a file exported with "Raw Export" + + ***************** + * File Header * + ***************** + * SLO Image * + ***************** + * B-Scan #0 * + ***************** + * ..... * + ***************** + * B-Scan #n-1 * + ***************** +*) + +With[{i = "Integer32", f = "Real32", d = "Real64", b = "Byte"}, + + $fileHeaderInfo = Transpose[{ + { + "Version" , "SizeX" , "NumBScans" , "SizeZ" , "ScaleX" , "Distance" , + "ScaleZ" , "SizeXSlo" , "SizeYSlo" , "ScaleXSlo" , "ScaleYSlo" , + "FieldSizeSlo" , "ScanFocus" , "ScanPosition" , "ExamTime" , + "ScanPattern" , "BScanHdrSize" , "ID" , "ReferenceID" , "PID" , + "PatientID" , "Padding" , "DOB" , "VID" , "VisitID" , "VisitDate" , + "Spare" + }, + { + {b, 12}, i, i, i, d, d, d, i, i, d, d, i, d, {b, 4}, {i, 2}, i, i, + {b, 16}, {b, 16}, i, {b, 21}, {b, 3}, d, i, {b, 24}, d, {b, 1840} + } + }]; + + $bScanHeaderInfo = Transpose[{ + { + "Version" , "BScanHdrSize" , "StartX" , "StartY" , "EndX" , "EndY" , + "NumSeg" , "OffSeg" , "Quality" , "Spare" + }, + {{b, 12}, i, d, d, d, d, i, i, f, {b, 196}} + }]; +]; + + +isHeyexRawFormat[{"Version" -> version_String, "SizeX" -> _Integer, "NumBScans" -> _Integer, _Rule..}] /; StringMatchQ[version, "HSF-OCT" ~~__] := True ; +isHeyexRawFormat[___] := False; + +readFileHeader[str_InputStream] := With[{hdr = Quiet[read[#, str]] & /@ $fileHeaderInfo}, + hdr /; TrueQ[isHeyexRawFormat[hdr]] +]; +readFileHeader[___] := (Message[HeyexImport::wrongHdr]; Throw[$Failed]); + + +(* Reads the camera image of the retina. Note that you must have the + information from the fileheader and you must be at the right position + of the file stream for this.*) +readSLOImage[str_InputStream, fileHdr : {(_String -> _) ..}] := + Image[Partition[ + BinaryReadList[str, "Byte" , "SizeXSlo" * "SizeYSlo" /. fileHdr], + "SizeXSlo" /. fileHdr], "Byte" ]; + +skipSLOImage[str_InputStream, fileHdr : {(_String -> _) ..}] := + Skip[str, "Byte" , "SizeXSlo" * "SizeYSlo" /. fileHdr]; + + +(* One single BScan consists itself again of a header and a data part *) +readBScanHeader[str_InputStream, fileHdr : {(_String -> _) ..}] := + Module[{i = "Integer32", f = "Real32", d = "Real64", b = "Byte", + bScanHdr}, + bScanHdr = read[#, str] & /@ Transpose[{ + { "Version" , "BScanHdrSize" , "StartX" , "StartY" , "EndX" , "EndY" , + "NumSeg" , "OffSeg" , "Quality" , "Spare" }, + {{b, 12}, i, d, d, d, d, i, i, f, {b, 196}}} + ]; + AppendTo[bScanHdr, + read[{ "SegArray" , { "Real32" , + "NumSeg" * "SizeX" /. bScanHdr /. fileHdr}}, str] + ]; + (* + This is horrible slow, therefore I just skip the fillbytes + + AppendTo[bScanHdr, + read[{"Fillbytes", {"Byte", + "BScanHdrSize" - 256 - "NumSeg"*"SizeX"*4 /. bScanHdr /. + fileHdr}}, str] + ] + *) + Skip[str, "Byte" , "BScanHdrSize" - 256 - "NumSeg" * "SizeX" * 4 /. bScanHdr /. fileHdr]; + AppendTo[bScanHdr, "FillBytes" -> None] + ] + +skipBScanHeader[str_InputStream, fileHdr : {(_String -> _) ..}] := + Skip[str, "Byte" , "BScanHdrSize" /. fileHdr]; + +readBScanData[str_InputStream, fileHdr : {(_String -> _) ..}] := + Module[{}, + Developer`ToPackedArray[ + Partition[read[{ "Real32" , "SizeX" * "SizeZ" /. fileHdr}, str], + "SizeX" /. fileHdr]] + ]; + +skipBScanData[str_InputStream, fileHdr : {(_String -> _) ..}] := + Skip[str, "Byte" , "SizeX" * "SizeZ" * 4 /. fileHdr]; + +skipBScanBlocks[str_InputStream, fileHdr : {(_String -> _) ..}, n_Integer] := + Skip[str, "Byte" , n * ("BScanHdrSize" + "SizeX" * "SizeZ" * 4) /. fileHdr]; + + +importHeader[filename_String, ___] := Module[ + {str, header}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + Close[str]; + "FileHeader" -> header +]; + + +(* Imports the dimension of the scanned volume. *) +importDataSize[filename_String, r___] := Module[{header = importHeader[filename]}, + "DataSize" -> ({"NumBScans", "SizeZ", "SizeXSlo"} /. ("FileHeader" /. header)) +] + +importSLOImage[filename_String, ___] := Module[ + {str, header, slo}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + slo = readSLOImage[str, header]; + Close[str]; + "SLOImage" -> slo +] + +importData[filename_String, ___] := Module[ + {str, header, nx, n, data}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + {nx, n} = { "SizeX" , "SizeX" * "SizeZ"} /. header; + skipSLOImage[str, header]; + data = Table[ + skipBScanHeader[str, header]; + Partition[read[{ "Real32" , n}, str], nx], + {"NumBScans" /. header} + ]; + Close[str]; + "Data" -> Developer`ToPackedArray[data] +]; + +importData[num_Integer][filename_String, ___] := Module[ + {str, header, nx, n, data}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + {nx, n} = { "SizeX" , "SizeX" * "SizeZ"} /. header; + skipSLOImage[str, header]; + skipBScanBlocks[str, header, Max[Min["NumBScans" /. header, num - 1], 0] ]; + skipBScanHeader[str, header]; + data = Partition[read[{ "Real32" , n}, str], nx]; + Close[str]; + {"Data" -> {num -> Developer`ToPackedArray[data]}} +]; + +(* + As suggested in the Heidelberg OCT Manual the importer will adjust + the graylevels when importing images. Since this is very time-consuming + for the whole scanned volume, I use an optimized version of this function. +*) +With[{$compileTarget = $compileTarget}, $adjustGraylevelFunc := ($adjustGraylevelFunc = Compile[{{values, _Real, 2}}, + Map[Floor[255.0 * Min[Max[0.0, #], 1.0]^(0.25) + 0.5] &, values, {2}], + RuntimeAttributes -> {Listable}, + Parallelization -> True, + RuntimeOptions -> "Speed", + $compileTarget +])]; + +importImages[filename_String, ___] := Module[ + {data}, + data = "Data" /. importData[filename]; + "Images" -> (Image[#, "Byte" ]& /@ $adjustGraylevelFunc[data]) +] + +importImages[imageNumber_Integer][filename_String, ___] := Module[ + {data}, + data = {imageNumber /. ("Data" /. importData[imageNumber][filename])}; + {"Images" -> {imageNumber -> (Image[#, "Byte" ]& @@ $adjustGraylevelFunc[data])}} +]; + +importSegmentation[filename_String, ___] := Module[ + {str, header, data}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + skipSLOImage[str, header]; + data = Table[ + Module[{bScanHeader, t}, + {t, bScanHeader} = Timing@readBScanHeader[str, header]; + skipBScanData[str, header]; + bScanHeader + ], {"NumBScans" /. header} + ]; + Close[str]; + (* + The BScanHeaderData contain the segmentation vectors as a single list + of numbers. Before returning the result, I check how many segmentations + there are inside the BScan an I transform the segmentation value list + into separate vectors and call them "ILM", "RPE" and "NFL" like described + in the manual + *) + "SegmentationData" -> Function[{bhdr}, + Block[{numVecs = "NumSeg" /. bhdr, vecNames, nx = "SizeX" /. header}, + If[numVecs > 0, + vecNames = Take[{ "ILM" , "RPE" , "NFL" }, numVecs]; + bhdr /. ("SegArray" -> vec_) :> Sequence @@ (Rule @@@ Transpose[{vecNames, Partition[vec, nx]} ]), + bhdr + ] + ]] /@ data +] + +importSegmentation[num_Integer][filename_String, ___] := Module[ + {str, header, bhdr}, + str = OpenRead[filename, BinaryFormat -> True]; + header = readFileHeader[str]; + skipSLOImage[str, header]; + skipBScanBlocks[str, header, Max[Min["NumBScans" /. header, num - 1], 0] ]; + bhdr = readBScanHeader[str, header]; + Close[str]; + (* See doc above *) + {"SegmentationData" -> {num -> Block[ + {numVecs = "NumSeg" /. bhdr, vecNames, nx = "SizeX" /. header}, + If[ numVecs > 0, + vecNames = Take[{ "ILM" , "RPE" , "NFL" }, numVecs]; + bhdr /. ("SegArray" -> vec_) :> Sequence @@ (Rule @@@ Transpose[{vecNames, Partition[vec, nx]} ]), + bhdr + ] + ] + }} +] + +(* Extracts which eye was scanned. This is stored in the header of the file *) +(* OD stands for oculus dexter which is latin for "right eye" and OS stands + for oculus sinister which is latin for "left eye" *) +HeyexEyePosition[file_String /; FileExistsQ[file]] := Module[{position}, + Check[ + position = "ScanPosition" /. Import[file, { "Heyex" , "FileHeader" }]; + Switch[ + position, + "OD" , + Right, + "OS" , + Left, + _, + $Failed + ], + $Failed + ] +]; + +End[] + +EndPackage[] \ No newline at end of file diff --git a/samples/Mercury/switch_detection_bug.m b/samples/Mercury/switch_detection_bug.m new file mode 100644 index 00000000..f96542c3 --- /dev/null +++ b/samples/Mercury/switch_detection_bug.m @@ -0,0 +1,46 @@ +% This is a regression test for a bug in switch detection +% where it was preferring incomplete switches to complete +% one-case switches, and hence inferring the wrong determinism. + +%------------------------------------------------------------------------------% + +:- module switch_detection_bug. + +:- interface. + +:- type note ---> note(rank, modifier, octave). + +:- type rank ---> c ; d ; e ; f ; g ; a ; b . + +:- type modifier ---> natural ; sharp ; flat . + +:- type octave == int. + +:- type qualifier ---> maj ; min . + +:- pred next_topnote(note, qualifier, note). +:- mode next_topnote(in, in, out) is multi. + +%------------------------------------------------------------------------------% + +:- implementation. + +next_topnote(note(c, _, Oct), _, note(d, natural, Oct)). +next_topnote(note(d, _, Oct), _, note(c, natural, Oct)). +next_topnote(note(d, _, Oct), maj, note(e, natural, Oct)). +next_topnote(note(d, _, Oct), min, note(e, flat, Oct)). +next_topnote(note(e, _, Oct), _, note(d, natural, Oct)). +next_topnote(note(e, _, Oct), _, note(f, natural, Oct)). +next_topnote(note(f, _, Oct), maj, note(e, natural, Oct)). +next_topnote(note(f, _, Oct), min, note(e, flat, Oct)). +next_topnote(note(g, _, Oct), _, note(f, natural, Oct)). +next_topnote(note(g, _, Oct), min, note(a, flat, Oct)). +next_topnote(note(g, _, Oct), maj, note(a, natural, Oct)). +next_topnote(note(a, _, Oct), _, note(g, natural, Oct)). +next_topnote(note(a, _, Oct), min, note(b, flat, Oct)). +next_topnote(note(a, _, Oct), maj, note(b, natural, Oct)). +next_topnote(note(b, _, Oct), maj, note(a, natural, Oct)). +next_topnote(note(b, _, Oct), min, note(a, flat, Oct)). + +%------------------------------------------------------------------------------% + diff --git a/samples/Modelica/Translational.mo b/samples/Modelica/Translational.mo new file mode 100644 index 00000000..62735f6a --- /dev/null +++ b/samples/Modelica/Translational.mo @@ -0,0 +1,5281 @@ +within Modelica.Mechanics; +package Translational + "Library to model 1-dimensional, translational mechanical systems" + extends Modelica.Icons.Package; + import SI = Modelica.SIunits; + + package Examples "Demonstration examples of the components of this package" + + extends Modelica.Icons.ExamplesPackage; + + model SignConvention "Examples for the used sign conventions." + extends Modelica.Icons.Example; + Translational.Components.Mass mass1(L=1, + s(fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{40,60},{60,80}}, rotation=0))); + Translational.Sources.Force force1 + annotation (Placement(transformation(extent={{ + -4,60},{16,80}}, rotation=0))); + Modelica.Blocks.Sources.Constant constant1(k=1) + annotation (Placement(transformation(extent={{ + -44,60},{-24,80}}, rotation=0))); + Translational.Components.Mass mass2(L=1, + s(fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{40,0},{60,20}}, rotation=0))); + Translational.Sources.Force force2 + annotation (Placement(transformation(extent={{ + -4,20},{16,40}}, rotation=0))); + Modelica.Blocks.Sources.Constant constant2(k=1) + annotation (Placement(transformation(extent={{ + -44,20},{-24,40}}, rotation=0))); + Translational.Components.Mass mass3(L=1, + s(fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{-40,-40},{-20,-20}}, rotation=0))); + Translational.Sources.Force force3(useSupport=true) + annotation (Placement(transformation(extent={{ + 20,-40},{0,-20}}, rotation=0))); + Modelica.Blocks.Sources.Constant constant3(k=1) + annotation (Placement(transformation(extent={{ + 60,-40},{40,-20}}, rotation=0))); + Translational.Components.Fixed fixed + annotation (Placement(transformation(extent={{0,-60},{20,-40}}))); + equation + connect(constant1.y,force1. f) annotation (Line(points={{-23,70},{-6,70}}, + color={0,0,127})); + connect(constant2.y,force2. f) annotation (Line(points={{-23,30},{-6,30}}, + color={0,0,127})); + connect(constant3.y,force3. f) annotation (Line(points={{39,-30},{22,-30}}, + color={0,0,127})); + connect(force1.flange, mass1.flange_a) annotation (Line( + points={{16,70},{40,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(force2.flange, mass2.flange_b) annotation (Line( + points={{16,30},{70,30},{70,10},{60,10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass3.flange_b, force3.flange) annotation (Line( + points={{-20,-30},{0,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed.flange, force3.support) annotation (Line( + points={{10,-50},{10,-40}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation (Documentation(info=" +

+If all arrows point in the same direction a positive force +results in a positive acceleration a, velocity v and position s. +

+

+For a force of 1 N and a mass of 1 Kg this leads to +

+
+        a = 1 m/s2
+        v = 1 m/s after 1 s (SlidingMass1.v)
+        s = 0.5 m after 1 s (SlidingMass1.s)
+
+

+The acceleration is not available for plotting. +

+

+System 1) and 2) are equivalent. It doesn't matter whether the +force pushes at flange_a in system 1 or pulls at flange_b in system 2. +

+It is of course possible to ignore the arrows and connect the models +in an arbitrary way. But then it is hard see in what direction the +force acts. +

+In the third system the two arrows are opposed which means that the +force acts in the opposite direction (in the same direction as in +the two other examples). +

+"), Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Text( + extent={{-100,80},{-82,60}}, + textString="1)", + lineColor={0,0,255}), + Text( + extent={{-100,40},{-82,20}}, + textString="2)", + lineColor={0,0,255}), + Text( + extent={{-100,-20},{-82,-40}}, + textString="3)", + lineColor={0,0,255})}), + experiment(StopTime=1.0, Interval=0.001)); + end SignConvention; + + model InitialConditions "Setting of initial conditions" + + extends Modelica.Icons.Example; + + Translational.Components.Fixed fixed2( s0=1) + annotation (Placement(transformation( + extent={{-100,60},{-80,80}}, rotation=0))); + Translational.Components.Spring s2( s_rel0=2, c=1e3) + annotation (Placement( + transformation(extent={{-60,60},{-40,80}}, rotation=0))); + Translational.Components.Mass m3( L=3, s(start=4.5, fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{-20,60},{0,80}}, rotation=0))); + Translational.Components.SpringDamper sd2( s_rel0=4, c=111, + d=1) annotation (Placement( + transformation(extent={{20,60},{40,80}}, rotation=0))); + Translational.Components.Mass m4( L=5, s(start=12.5, fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{60,60},{80,80}}, rotation=0))); + + Translational.Components.Fixed fixed1( s0=-1) + annotation (Placement(transformation( + extent={{-100,-20},{-80,0}}, rotation=0))); + Translational.Components.Spring s1( + s_rel0=1, + c=1e3, + s_rel(start=1, fixed=true)) + annotation (Placement(transformation(extent={{-58,-20}, + {-38,0}}, rotation=0))); + Translational.Components.Mass m1( L=1, v(fixed=true), + m=1) annotation (Placement(transformation( + extent={{-20,-20},{0,0}}, rotation=0))); + Translational.Components.SpringDamper sd1( + s_rel0=1, + c=111, + s_rel(start=1, fixed=true), + v_rel(fixed=true), + d=1) annotation (Placement(transformation(extent={{20,-20},{ + 40,0}}, rotation=0))); + Translational.Components.Mass m2( L=2, m=1) + annotation (Placement(transformation( + extent={{60,-20},{80,0}}, rotation=0))); + equation + connect(s2.flange_a, fixed2.flange) annotation (Line( + points={{-60,70},{-90,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(s1.flange_a, fixed1.flange) annotation (Line( + points={{-58,-10},{-90,-10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(m1.flange_a, s1.flange_b) annotation (Line( + points={{-20,-10},{-38,-10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(sd1.flange_a, m1.flange_b) annotation (Line( + points={{20,-10},{0,-10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(m2.flange_a, sd1.flange_b) annotation (Line( + points={{60,-10},{40,-10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(m4.flange_a, sd2.flange_b) annotation (Line( + points={{60,70},{40,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(sd2.flange_a, m3.flange_b) annotation (Line( + points={{20,70},{0,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(m3.flange_a, s2.flange_b) annotation (Line( + points={{-20,70},{-40,70}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+There are several ways to set initial conditions. +In the first system the position of the mass m3 was defined +by using the modifier s(start=4.5), the position of m4 by s(start=12.5). +These positions were chosen such that the system is a rest. To calculate +these values start at the left (Fixed1) with a value of 1 m. The spring +has an unstretched length of 2 m and m3 an length of 3 m, which leads to +

+ +
+        1   m (fixed1)
+      + 2   m (spring s2)
+      + 3/2 m (half of the length of mass m3)
+      -------
+        4,5 m = s(start = 4.5) for m3
+      + 3/2 m (half of the length of mass m3)
+      + 4   m (springDamper 2)
+      + 5/2 m (half of length of mass m4)
+      -------
+       12,5 m = s(start = 12.5) for m4
+
+ +

+This selection of initial conditions has the effect that Dymola selects +those variables (m3.s and m4.s) as state variables. +In the second example the length of the springs are given as start values +but they cannot be used as state for pure springs (only for the spring/damper +combination). In this case the system is not at rest. +

+ +

+ +

+ +"), + experiment(StopTime=5.0, Interval=0.001)); + end InitialConditions; + + model WhyArrows "Use of arrows in Mechanics.Translational" + + extends Modelica.Icons.Example; + + Translational.Components.Fixed fixed + annotation (Placement(transformation(extent={{ + -20,20},{0,40}}, rotation=0))); + Translational.Components.Rod rod1( L=1) + annotation (Placement(transformation(extent={ + {-48,20},{-28,40}}, rotation=0))); + Translational.Components.Rod rod2( L=1) + annotation (Placement(transformation(extent={ + {20,20},{40,40}}, rotation=0))); + Translational.Components.Rod rod3( L=1) + annotation (Placement(transformation(extent={ + {-30,58},{-50,78}}, rotation=0))); + Translational.Sensors.PositionSensor positionSensor2 annotation (Placement( + transformation(extent={{60,20},{80,40}}, rotation=0))); + Translational.Sensors.PositionSensor positionSensor1 annotation (Placement( + transformation(extent={{-60,20},{-80,40}}, rotation=0))); + Translational.Sensors.PositionSensor positionSensor3 annotation (Placement( + transformation(extent={{-60,58},{-80,78}}, rotation=0))); + Translational.Components.Fixed fixed1( s0=-1.9) + annotation (Placement(transformation( + extent={{-100,-60},{-80,-40}}, rotation=0))); + Translational.Components.Spring spring1( s_rel0=2, c=11) + annotation (Placement( + transformation(extent={{-80,-60},{-60,-40}}, rotation=0))); + Translational.Components.Mass mass1( + L=2, + s(fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{-50,-60},{-30,-40}}, rotation=0))); + Translational.Components.Fixed fixed2( s0=-1.9) + annotation (Placement(transformation( + extent={{0,-60},{20,-40}}, rotation=0))); + Translational.Components.Spring spring2( s_rel0=2, c=11) + annotation (Placement( + transformation(extent={{30,-60},{50,-40}}, rotation=0))); + Translational.Components.Mass inertia2( L=2, + m=1, + s(fixed=true), + v(fixed=true)) annotation (Placement( + transformation(extent={{80,-60},{60,-40}}, rotation=0))); + equation + connect(spring1.flange_b, mass1.flange_b) annotation (Line(points={{-60,-50}, + {-60,-72},{-30,-72},{-30,-50}}, color={0,191,0})); + connect(spring2.flange_b, inertia2.flange_b) annotation (Line(points={{50,-50}, + {60,-50}}, color={0,191,0})); + connect(rod3.flange_b,positionSensor3. flange) annotation (Line( + points={{-50,68},{-60,68}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod1.flange_a,positionSensor1. flange) annotation (Line( + points={{-48,30},{-60,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod1.flange_b, fixed.flange) annotation (Line( + points={{-28,30},{-10,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod3.flange_a, fixed.flange) annotation (Line( + points={{-30,68},{-10,68},{-10,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed.flange, rod2.flange_a) annotation (Line( + points={{-10,30},{20,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod2.flange_b,positionSensor2. flange) annotation (Line( + points={{40,30},{60,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed1.flange,spring1. flange_a) annotation (Line( + points={{-90,-50},{-80,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed2.flange,spring2. flange_a) annotation (Line( + points={{10,-50},{30,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+When using the models of the translational sublibrary +it is recommended to make sure that all arrows point in +the same direction because then all component have the +same reference system. +In the example the distance from flange_a of Rod1 to flange_b +of Rod2 is 2 m. The distance from flange_a of Rod1 to flange_b +of Rod3 is also 2 m though it is difficult to see that. Without +the arrows it would be almost impossible to notice. +That all arrows point in the same direction is a sufficient +condition for an easy use of the library. There are cases +where horizontally flipped models can be used without +problems. +

+"), Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-84,10},{88,2}}, + lineColor={0,0,255}, + textString="positionSensor2.s = positionSensor3.s"), + Text( + extent={{-78,-4},{86,-12}}, + lineColor={0,0,255}, + textString="positionSensor3.s <>positionSensor1.s"), + Text( + extent={{-82,-80},{92,-88}}, + textString="Both systems are equivalent", + lineColor={0,0,255}), + Line( + points={{-90,-28},{90,-28}}, + thickness=0.5, + color={0,0,255})}), + experiment(StopTime=1.0, Interval=0.001)); + end WhyArrows; + + model Accelerate "Use of model accelerate." + + extends Modelica.Icons.Example; + Translational.Sources.Accelerate accelerate + annotation (Placement(transformation( + extent={{-40,20},{-20,40}}, rotation=0))); + Translational.Components.Mass mass(L=1, m=1) + annotation (Placement( + transformation(extent={{0,20},{20,40}}, rotation=0))); + Modelica.Blocks.Sources.Constant constantAcc(k=1) + annotation (Placement(transformation(extent={{-80,20}, + {-60,40}}, rotation=0))); + equation + connect(accelerate.flange, mass.flange_a) annotation (Line( + points={{-20,30},{0,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(constantAcc.y, accelerate.a_ref) annotation (Line( + points={{-59,30},{-42,30}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Documentation(info=" +

+Demonstrate usage of component Sources.Accelerate by moving a massing +with a predefined acceleration. +

+"), experiment(StopTime=1.0, Interval=0.001)); + end Accelerate; + + model Damper "Use of damper models." + + extends Modelica.Icons.Example; + + Translational.Components.Mass mass1( + L=1, + s(start=3, fixed=true), + v(start=10, fixed=true), + m=1) annotation (Placement(transformation(extent={{-80,60},{-60, + 80}}, rotation=0))); + Translational.Components.Damper damper1( d=25) + annotation (Placement(transformation( + extent={{-20,60},{0,80}}, rotation=0))); + Translational.Components.Fixed fixed1( s0=4.5) + annotation (Placement(transformation( + extent={{22,60},{42,80}}, rotation=0))); + Translational.Components.Mass mass2( + L=1, + s(start=3, fixed=true), + v(start=10, fixed=true), + m=1) annotation (Placement(transformation(extent={{-80,0},{-60, + 20}}, rotation=0))); + Translational.Components.Damper damper2( d=25) + annotation (Placement(transformation( + extent={{-20,0},{0,20}}, rotation=0))); + Translational.Components.Fixed fixed2( s0=4.5) + annotation (Placement(transformation( + extent={{20,0},{40,20}}, rotation=0))); + Translational.Components.Mass mass3( + L=1, + s(start=3, fixed=true), + v(start=10, fixed=true), + m=1) annotation (Placement(transformation(extent={{-80,-60},{-60, + -40}}, rotation=0))); + Translational.Components.Fixed fixed3( s0=4.5) + annotation (Placement(transformation( + extent={{20,-60},{40,-40}}, rotation=0))); + Translational.Components.Spring spring2( s_rel0=1, c=1) + annotation (Placement( + transformation(extent={{-20,-20},{0,0}}, rotation=0))); + Translational.Components.SpringDamper springDamper3( s_rel0=1, d=25, + c=1) annotation (Placement( + transformation(extent={{-20,-60},{0,-40}}, rotation=0))); + equation + connect(mass1.flange_b, damper1.flange_a) annotation (Line(points= + {{-60,70},{-20,70}}, color={0,191,0})); + connect(mass2.flange_b, damper2.flange_a) annotation (Line(points={{-60,10}, + {-20,10}}, color={0,191,0})); + connect(damper2.flange_b,spring2. flange_b) annotation (Line(points={{0, + 10},{0,-10}}, color={0,191,0})); + connect(damper2.flange_a,spring2. flange_a) annotation (Line(points={{-20, + 10},{-20,-10}}, color={0,191,0})); + connect(mass3.flange_b, springDamper3.flange_a) annotation (Line( + points={{-60,-50},{-20,-50}}, color={0,191,0})); + connect(damper1.flange_b, fixed1.flange) annotation (Line( + points={{0,70},{32,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(damper2.flange_b, fixed2.flange) annotation (Line( + points={{0,10},{30,10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper3.flange_b, fixed3.flange) annotation (Line( + points={{0,-50},{30,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation (Documentation(info=" +

+Demonstrate usage of damper components in different variants. +

+"), + experiment(StopTime=1.0, Interval=0.001)); + end Damper; + + model Oscillator "Oscillator demonstrates the use of initial conditions." + + extends Modelica.Icons.Example; + + Translational.Components.Mass mass1( + L=1, + s(start=-0.5, fixed=true), + v(start=0, fixed=true), + m=1) annotation (Placement(transformation(extent={{-20,40},{0, + 60}}, rotation=0))); + Translational.Components.Spring spring1( s_rel0=1, c=10000) + annotation (Placement( + transformation(extent={{20,40},{40,60}}, rotation=0))); + Translational.Components.Fixed fixed1( s0=1) + annotation (Placement(transformation( + extent={{60,40},{80,60}}, rotation=0))); + Translational.Sources.Force force1 + annotation (Placement(transformation(extent={{ + -60,40},{-40,60}}, rotation=0))); + Modelica.Blocks.Sources.Sine sine1(freqHz=15.9155) annotation (Placement(transformation( + extent={{-100,40},{-80,60}}, rotation=0))); + Translational.Components.Mass mass2( + L=1, + s(start=-0.5, fixed=true), + v(start=0, fixed=true), + m=1) annotation (Placement(transformation(extent={{-20,-60},{0, + -40}}, rotation=0))); + Translational.Components.Spring spring2( s_rel0=1, c=10000) + annotation (Placement( + transformation(extent={{20,-60},{40,-40}}, rotation=0))); + Translational.Components.Fixed fixed2( s0=1) + annotation (Placement(transformation( + extent={{60,-60},{80,-40}}, rotation=0))); + Translational.Sources.Force force2 + annotation (Placement(transformation(extent={{ + -60,-60},{-40,-40}}, rotation=0))); + Modelica.Blocks.Sources.Sine sine2(freqHz=15.9155) annotation (Placement(transformation( + extent={{-100,-60},{-80,-40}}, rotation=0))); + Translational.Components.Damper damper1( d=10) + annotation (Placement(transformation( + extent={{20,-36},{40,-16}}, rotation=0))); + equation + connect(mass1.flange_b, spring1.flange_a) annotation (Line(points= + {{0,50},{20,50}}, color={0,191,0})); + connect(spring2.flange_a,damper1. flange_a) annotation (Line(points={{20, + -50},{20,-26}}, color={0,191,0})); + connect(mass2.flange_b, spring2.flange_a) annotation (Line(points= + {{0,-50},{20,-50}}, color={0,191,0})); + connect(damper1.flange_b,spring2. flange_b) annotation (Line(points={{40, + -26},{40,-50}}, color={0,191,0})); + connect(sine1.y,force1. f) annotation (Line(points={{-79,50},{-62,50}}, + color={0,0,127})); + connect(sine2.y,force2. f) annotation (Line(points={{-79,-50},{-62,-50}}, + color={0,0,127})); + connect(spring1.flange_b, fixed1.flange) annotation (Line( + points={{40,50},{70,50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(force2.flange, mass2.flange_a) annotation (Line( + points={{-40,-50},{-20,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(force1.flange, mass1.flange_a) annotation (Line( + points={{-40,50},{-20,50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(spring2.flange_b, fixed2.flange) annotation (Line( + points={{40,-50},{70,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+A spring - mass system is a mechanical oscillator. If no +damping is included and the system is excited at resonance +frequency infinite amplitudes will result. +The resonant frequency is given by +omega_res = sqrt(c / m) +with: +

+ +
+      c spring stiffness
+      m mass
+
+ +

+To make sure that the system is initially at rest the initial +conditions s(start=0) and v(start=0) for the SlidingMass +are set. +If damping is added the amplitudes are bounded. +

+"), + experiment(StopTime=1.0, Interval=0.001)); + end Oscillator; + + model Sensors "Sensors for translational systems." + import Modelica; + + extends Modelica.Icons.Example; + + Translational.Sensors.ForceSensor forceSensor annotation (Placement( + transformation(extent={{-34,40},{-14,60}}, + rotation=0))); + Translational.Sensors.SpeedSensor speedSensor1 annotation (Placement( + transformation(extent={{40,-40},{60,-20}}, rotation=0))); + Translational.Sensors.PositionSensor positionSensor1 annotation (Placement( + transformation(extent={{40,0},{60,20}}, rotation=0))); + Translational.Sensors.AccSensor accSensor1 annotation (Placement( + transformation(extent={{40,-80},{60,-60}}, rotation=0))); + Translational.Components.Mass mass(L=1, + s(fixed=true), + v(fixed=true), + m=1) annotation (Placement( + transformation(extent={{20,40},{40,60}}, rotation=0))); + Translational.Sources.Force force + annotation (Placement(transformation(extent={{-64,40}, + {-44,60}}, rotation=0))); + Modelica.Blocks.Sources.Sine sineForce(amplitude=10, freqHz=4) + annotation (Placement( + transformation(extent={{-100,40},{-80,60}}, rotation=0))); + Translational.Sensors.PositionSensor positionSensor2 annotation (Placement( + transformation(extent={{60,40},{80,60}}, rotation=0))); + Modelica.Mechanics.Translational.Sensors.MultiSensor multiSensor + annotation (Placement(transformation(extent={{-8,40},{12,60}}))); + equation + connect(sineForce.y, force.f) + annotation (Line(points={{-79,50},{-66,50}}, + color={0,0,127})); + connect(forceSensor.flange_a, force.flange) annotation (Line( + points={{-34,50},{-44,50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass.flange_a, positionSensor1.flange) annotation (Line( + points={{20,50},{20,10},{40,10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass.flange_a, speedSensor1.flange) annotation (Line( + points={{20,50},{20,-30},{40,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass.flange_a, accSensor1.flange) annotation (Line( + points={{20,50},{20,-70},{40,-70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass.flange_b, positionSensor2.flange) annotation (Line( + points={{40,50},{60,50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(forceSensor.flange_b, multiSensor.flange_a) annotation (Line( + points={{-14,50},{-8,50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(multiSensor.flange_b, mass.flange_a) annotation (Line( + points={{12,50},{20,50}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+These sensors measure +

+ +
+   force f in N
+   position s in m
+   velocity v in m/s
+   acceleration a in m/s2
+
+ +

+The measured velocity and acceleration is independent on +the flange the sensor is connected to. The position +depends on the flange (flange_a or flange_b) and the +length L of the component. +Plot PositionSensor1.s, PositionSensor2.s and SlidingMass1.s +to see the difference. +

+"), + experiment(StopTime=1.0, Interval=0.001)); + end Sensors; + + model Friction "Use of model Stop" + extends Modelica.Icons.Example; + Modelica.Mechanics.Translational.Components.MassWithStopAndFriction stop1( + L=1, + s(fixed=true), + v(fixed=true), + smax=25, + smin=-25, + m=1, + F_prop=1, + F_Coulomb=5, + F_Stribeck=10, + fexp=2) annotation (Placement(transformation(extent={{20,60}, + {40,80}}, rotation=0))); + Translational.Sources.Force force + annotation (Placement(transformation(extent={{-20,60}, + {0,80}}, rotation=0))); + Modelica.Blocks.Sources.Sine sineForce(amplitude=25, freqHz=0.25) + annotation (Placement( + transformation(extent={{-60,60},{-40,80}}, + rotation=0))); + Modelica.Mechanics.Translational.Components.MassWithStopAndFriction stop2( + L=1, + smax=0.9, + smin=-0.9, + F_Coulomb=3, + F_Stribeck=5, + s(start=0, fixed=true), + m=1, + F_prop=1, + fexp=2, + v(start=-5, fixed=true)) + annotation (Placement(transformation(extent={{42,-60},{62, + -40}}, + rotation=0))); + Translational.Components.Spring spring(s_rel0=1, c=500) + annotation (Placement( + transformation(extent={{2,-60},{22,-40}}, + rotation=0))); + Translational.Components.Fixed fixed2(s0=-1.75) + annotation (Placement(transformation( + extent={{-40,-60},{-20,-40}}, + rotation=0))); + Translational.Sources.Force force2 + annotation (Placement(transformation(extent={{-22,0}, + {-2,20}}, rotation=0))); + Components.Mass mass( + m=1, + L=1, + s(fixed=true), + v(fixed=true)) + annotation (Placement(transformation(extent={{10,0},{30,20}}))); + Components.SupportFriction supportFriction(f_pos= + Examples.Utilities.GenerateStribeckFrictionTable( + F_prop=1, + F_Coulomb=5, + F_Stribeck=10, + fexp=2, + v_max=12, + nTable=50)) + annotation (Placement(transformation(extent={{40,0},{60,20}}))); + equation + connect(spring.flange_b, stop2.flange_a) annotation (Line(points={{22,-50}, + {42,-50}},color={0,191,0})); + connect(sineForce.y, force.f) + annotation (Line(points={{-39,70},{-22,70}}, + color={0,0,127})); + connect(spring.flange_a, fixed2.flange) annotation (Line( + points={{2,-50},{-30,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(force.flange, stop1.flange_a) annotation (Line( + points={{0,70},{20,70}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(force2.flange, mass.flange_a) annotation (Line( + points={{-2,10},{10,10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass.flange_b, supportFriction.flange_a) annotation (Line( + points={{30,10},{40,10}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(sineForce.y, force2.f) annotation (Line( + points={{-39,70},{-30,70},{-30,10},{-24,10}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation ( + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-100,80},{-80,60}}, + textString="1)", + lineColor={0,0,255}), + Text( + extent={{-100,20},{-80,0}}, + textString="2)", + lineColor={0,0,255}), + Text( + extent={{-100,-40},{-80,-60}}, + lineColor={0,0,255}, + textString="3)")}), + Documentation(info=" +
    +
  1. Simulate and then plot stop1.f as a function of stop1.v + This gives the Stribeck curve.
  2. +
  3. The same model is also available by modeling the system with a Mass and + a SupportFriction model. The SupportFriction model defines the friction characteristic + with a table. The table is constructed with function + Examples.Utilities.GenerateStribeckFrictionTable(..) to generate the + same friction characteristic as with stop1. + The simulation results of stop1 and of model mass are therefore identical.
  4. +
  5. Model stop2 gives an example for a hard stop. However there + can arise some problems with the used modeling approach (use of + reinit(..), convergence problems). In this case use the ElastoGap + to model a stop (see example Preload).
  6. +
+"), + experiment(StopTime=5.0, Interval=0.001)); + end Friction; + + model PreLoad "Preload of a spool using ElastoGap models." + + extends Modelica.Icons.Example; + + Translational.Components.ElastoGap innerContactA( + c=1000e3, + d=250, + s_rel0=0.001) + annotation (Placement(transformation(extent={{-70,20},{-50,40}}, + rotation=0))); + Translational.Components.ElastoGap innerContactB( + c=1000e3, + d=250, + s_rel0=0.001) + annotation ( Placement( + transformation(extent={{50,20},{70,40}}, rotation=0))); + Translational.Components.Mass spool( + L=0.19, + m=0.150, + s(start=0.01475, fixed=true), + v(fixed=true)) annotation (Placement(transformation(extent={{0,-40}, + {40,0}}, rotation=0))); + Translational.Components.Fixed fixedLe( s0=-0.0955) + annotation (Placement( + transformation(extent={{-10,-10},{10,10}}, rotation=270, + origin={-80,90}))); + Translational.Components.Mass springPlateA( + m=10e-3, + L=0.002, + s(start=-0.093, fixed=true), + v(fixed=true)) annotation (Placement(transformation(extent={{-38,60}, + {-18,80}}, rotation=0))); + Translational.Components.Mass springPlateB( + m=10e-3, + s(start=-0.06925, fixed=true), + L=0.002, + v(fixed=true)) annotation ( + Placement(transformation(extent={{20,60},{40,80}}, rotation=0))); + Translational.Components.Spring spring( c=20e3, s_rel0=0.025) + annotation (Placement(transformation(extent={{-10,60},{10,80}},rotation= + 0))); + Translational.Components.ElastoGap outerContactA( + c=1000e3, + d=250, + s_rel0=0.0015) + annotation (Placement(transformation(extent={{-70,60},{-50,80}}, + rotation=0))); + Translational.Components.ElastoGap outerContactB( + c=1000e3, + d=250, + s_rel0=0.0015) annotation (Placement(transformation(extent={{50,60},{70, + 80}}, rotation=0))); + Translational.Components.Rod rod1( L=0.007) + annotation (Placement(transformation( + extent={{-40,30},{-20,50}}, rotation=0))); + Translational.Components.Damper friction( d=2500) + annotation (Placement( + transformation( + origin={-80,50}, + extent={{-10,-10},{10,10}}, + rotation=270))); + Translational.Sources.Force force + annotation (Placement(transformation(extent={{-38,-30}, + {-18,-10}}, rotation=0))); + Translational.Components.Rod housing( L=0.0305) + annotation (Placement(transformation( + extent={{-10,80},{10,100}}, + rotation=0))); + Translational.Components.Rod rod3( L=0.00575) + annotation (Placement(transformation( + extent={{-40,-2},{-20,18}}, rotation=0))); + Translational.Components.Rod rod4( L=0.00575) + annotation (Placement(transformation( + extent={{20,-2},{40,18}}, rotation=0))); + Translational.Components.Rod rod2( L=0.007) + annotation (Placement(transformation( + extent={{20,30},{40,50}}, rotation=0))); + Modelica.Blocks.Sources.Sine sineForce(amplitude=150, freqHz=0.01) + annotation (Placement(transformation(extent={{-78,-30},{-58,-10}}, + rotation=0))); + equation + connect(outerContactA.flange_b,springPlateA. flange_a) annotation (Line( + points={{-50,70},{-38,70}}, color={0,191,0})); + connect(springPlateA.flange_b,spring. flange_a) annotation (Line(points={{-18,70}, + {-18,70},{-10,70}},color={0,191,0})); + connect(spring.flange_b,springPlateB. flange_a) annotation (Line(points={{10,70}, + {20,70}}, color={0,191,0})); + connect(springPlateB.flange_b,outerContactB. flange_a) annotation (Line( + points={{40,70},{40,70},{50,70}}, + color={0,191,0})); + connect(outerContactB.flange_b,housing. flange_b) annotation (Line(points={{70,70}, + {70,90},{10,90}}, color={0,191,0})); + connect(springPlateA.flange_b,rod1. flange_a) annotation (Line(points={{-18,70}, + {-18,52},{-40,52},{-40,40}}, color={0,191,0})); + connect(innerContactA.flange_a,rod3. flange_a) annotation (Line(points={{-70,30}, + {-80,30},{-80,8},{-40,8}}, color={0,191,0})); + connect(innerContactA.flange_b,rod1. flange_b) annotation (Line(points={{-50,30}, + {-20,30},{-20,40}}, color={0,191,0})); + connect(rod2.flange_a,innerContactB. flange_a) annotation (Line(points={{20,40}, + {20,30},{50,30}}, color={0,191,0})); + connect(rod4.flange_b,innerContactB. flange_b) annotation (Line(points={{40,8},{ + 70,8},{70,30}}, color={0,191,0})); + connect(friction.flange_b,rod3. flange_a) annotation (Line(points={{-80,40}, + {-80,8},{-40,8}}, color={0,191,0})); + connect(rod3.flange_b,rod4. flange_a) annotation (Line(points={{-20,8},{ + 20,8}}, color={0,191,0})); + connect(rod2.flange_b,springPlateB. flange_a) annotation (Line(points={{40,40}, + {40,52},{20,52},{20,70}}, color={0,191,0})); + connect(spool.flange_a,rod4. flange_a) annotation (Line(points={{0,-20},{ + 0,8},{20,8}}, color={0,191,0})); + connect(sineForce.y, force.f) + annotation (Line(points={{-57,-20},{-46,-20},{ + -40,-20}}, + color={0,0,127})); + connect(force.flange, spool.flange_a) annotation (Line( + points={{-18,-20},{0,-20}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(outerContactA.flange_a, fixedLe.flange) annotation (Line( + points={{-70,70},{-80,70},{-80,90}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(housing.flange_a, fixedLe.flange) annotation (Line( + points={{-10,90},{-80,90}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(friction.flange_a, fixedLe.flange) annotation (Line( + points={{-80,60},{-80,90}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-92,-72},{90,-80}}, + textString="positive force => spool moves in positive direction ", + lineColor={0,0,255}), + Text( + extent={{-48,-52},{42,-60}}, + textString="Simulate for 100 s", + lineColor={0,0,255}), + Text( + extent={{-100,-62},{88,-70}}, + lineColor={0,0,255}, + textString="plot spool.s as a function of force.f")}), + Documentation(info=" +

+When designing hydraulic valves it is often necessary to hold the spool in +a certain position as long as an external force is below a threshold value. +If this force exceeds the threshold value a linear relation between force +and position is desired. +There are designs that need only one spring to accomplish this task. Using +the ElastoGap elements this design can be modelled easily. +Drawing of spool. +

+ +

+
+
+
+

+ +

+Spool position s as a function of working force f. +

+ +

+ +

+"), + experiment(StopTime=100, Interval=0.1)); + end PreLoad; + + model ElastoGap "Demonstrate usage of ElastoGap" + extends Modelica.Icons.Example; + Components.Fixed fixed + annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); + Components.Rod rod1(L=2) + annotation (Placement(transformation(extent={{-40,-10},{-20,10}}))); + Components.Rod rod2(L=2) + annotation (Placement(transformation(extent={{20,-10},{40,10}}))); + Components.SpringDamper springDamper1( + c=10, + s_rel0=1, + s_rel(fixed=false, start=1), + d=1.5) + annotation (Placement(transformation(extent={{-40,20},{-20,40}}))); + Components.SpringDamper springDamper2( + c=10, + s_rel0=1, + s_rel(fixed=false, start=1), + d=1.5) + annotation (Placement(transformation(extent={{20,20},{40,40}}))); + Components.Mass mass1( + s(fixed=true, start=2), + L=0, + m=1, + v(fixed=true)) + annotation (Placement(transformation(extent={{-10,20},{10,40}}))); + Components.ElastoGap elastoGap1( + c=10, + s_rel(fixed=false, start=1.5), + s_rel0=1.5, + d=1.5) + annotation (Placement(transformation(extent={{-40,-40},{-20,-20}}))); + Components.ElastoGap elastoGap2( + c=10, + s_rel(fixed=false, start=1.5), + s_rel0=1.5, + d=1.5) + annotation (Placement(transformation(extent={{20,-40},{40,-20}}))); + Components.Mass mass2( + s(fixed=true, start=2), + L=0, + m=1, + v(fixed=true)) + annotation (Placement(transformation(extent={{-10,-40},{10,-20}}))); + parameter SI.TranslationalDampingConstant d=1.5 "Damping constant"; + equation + + connect(rod1.flange_b, fixed.flange) annotation (Line( + points={{-20,0},{0,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed.flange, rod2.flange_a) annotation (Line( + points={{0,0},{20,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper1.flange_a, rod1.flange_a) annotation (Line( + points={{-40,30},{-48,30},{-48,0},{-40,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper2.flange_b, rod2.flange_b) annotation (Line( + points={{40,30},{50,30},{50,0},{40,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper1.flange_b, mass1.flange_a) annotation (Line( + points={{-20,30},{-10,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass1.flange_b, springDamper2.flange_a) annotation (Line( + points={{10,30},{20,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod1.flange_a, elastoGap1.flange_a) annotation (Line( + points={{-40,0},{-48,0},{-48,-30},{-40,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(rod2.flange_b, elastoGap2.flange_b) annotation (Line( + points={{40,0},{50,0},{50,-30},{40,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(elastoGap1.flange_b, mass2.flange_a) annotation (Line( + points={{-20,-30},{-10,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass2.flange_b, elastoGap2.flange_a) annotation (Line( + points={{10,-30},{20,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+This model demonstrates the effect of ElastoGaps on eigenfrequency:
+Plot mass1.s and mass2.s as well as mass1.v and mass2.v

+mass1 is moved by both spring forces all the time.
+Since elastoGap1 lifts off at s > -0.5 m and elastoGap2 lifts off s < +0.5 m, +mass2 moves freely as long as -0.5 m < s < +0.5 m. +

+"), + experiment(StopTime=1.0, Interval=0.01)); + end ElastoGap; + + model Brake "Demonstrate braking of a translational moving mass" + extends Modelica.Icons.Example; + + Modelica.Mechanics.Translational.Components.Brake brake(fn_max=1, useSupport= + false) + annotation (Placement(transformation(extent={{6,40},{26,20}}))); + Modelica.Mechanics.Translational.Components.Mass mass1(m=1, + s(fixed=true), + v(start=1, fixed=true)) + annotation (Placement(transformation(extent={{-34,20},{-14,40}}))); + Modelica.Blocks.Sources.Step step(startTime=0.1, height=2) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, + rotation=0, + origin={-24,-10}))); + Modelica.Mechanics.Translational.Components.Brake brake1( + fn_max=1, useSupport= + true) + annotation (Placement(transformation(extent={{6,-60},{26,-40}}))); + Modelica.Mechanics.Translational.Components.Mass mass2(m=1, + s(fixed=true), + v(start=1, fixed=true)) + annotation (Placement(transformation(extent={{-34,-60},{-14,-40}}))); + Modelica.Mechanics.Translational.Components.Fixed fixed + annotation (Placement(transformation(extent={{6,-80},{26,-60}}))); + equation + connect(mass1.flange_b, brake.flange_a) + annotation (Line( + points={{-14,30},{6,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(step.y, brake.f_normalized) annotation (Line( + points={{-13,-10},{16,-10},{16,19}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(mass2.flange_b, brake1.flange_a) + annotation (Line( + points={{-14,-50},{6,-50}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(step.y, brake1.f_normalized) annotation (Line( + points={{-13,-10},{16,-10},{16,-39}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(fixed.flange, brake1.support) annotation (Line( + points={{16,-70},{16,-60}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( Documentation(info=" +

+This model consists of a mass with an initial velocity of 1 m/s. +After 0.1 s, a brake is activated and it is shown that the mass decelerates until +it arrives at rest and remains at rest. Two versions of this system are present, +one where the brake is implicitly grounded and one where it is explicitly grounded. +

+"), + experiment(StopTime=2.0, Interval=0.001)); + end Brake; + + model HeatLosses "Demonstrate the modeling of heat losses" + extends Modelica.Icons.Example; + Components.Mass mass1( + m=1, + s(fixed=true), + L=0.1, + v(fixed=true)) + annotation (Placement(transformation(extent={{-60,20},{-40,40}}))); + Components.SpringDamper springDamper( + s_rel(fixed=true), + v_rel(fixed=true), + c=100, + d=10, + useHeatPort=true) + annotation (Placement(transformation(extent={{-30,20},{-10,40}}))); + Components.Damper damper(d=10, useHeatPort=true) + annotation (Placement(transformation(extent={{-10,10},{10,-10}}, + rotation=-90, + origin={-60,-10}))); + Components.ElastoGap elastoGap( + c=100, + d=20, + s_rel0=-0.02, + useHeatPort=true) + annotation (Placement(transformation(extent={{-90,-10},{-70,10}}))); + Components.Fixed fixed1 + annotation (Placement(transformation(extent={{-70,-40},{-50,-20}}))); + Sources.Force force + annotation (Placement(transformation(extent={{-90,20},{-70,40}}))); + Blocks.Sources.Sine sine1(freqHz=1, amplitude=20) + annotation (Placement(transformation(extent={{-120,20},{-100,40}}))); + Components.Mass mass2( + m=1, + L=0.1, + s(fixed=false), + v(fixed=false)) + annotation (Placement(transformation(extent={{0,20},{20,40}}))); + Components.SupportFriction supportFriction(useHeatPort=true) + annotation (Placement(transformation(extent={{30,20},{50,40}}))); + Components.Spring spring(c=100, s_rel(fixed=true)) + annotation (Placement(transformation(extent={{60,20},{80,40}}))); + Components.Mass mass3( + m=1, + L=0.1, + s(fixed=false), + v(fixed=true)) + annotation (Placement(transformation(extent={{90,20},{110,40}}))); + Components.Brake brake(fn_max=10, useHeatPort=true) + annotation (Placement(transformation(extent={{120,20},{140,40}}))); + Blocks.Sources.Sine sine2(amplitude=10, freqHz=2) + annotation (Placement(transformation(extent={{100,50},{120,70}}))); + Components.MassWithStopAndFriction massWithStopAndFriction( + L=0.1, + m=1, + F_prop=0.5, + F_Coulomb=1, + F_Stribeck=2, + fexp=2, + smin=0, + smax=0.4, + v(fixed=true), + useHeatPort=true) + annotation (Placement(transformation(extent={{180,20},{200,40}}))); + Thermal.HeatTransfer.Components.Convection convection + annotation (Placement(transformation(extent={{-10,-40},{10,-60}}))); + Blocks.Sources.Constant const(k=20) + annotation (Placement(transformation(extent={{-30,-90},{-10,-70}}))); + Thermal.HeatTransfer.Celsius.FixedTemperature TAmbient(T=25) + "Ambient temperature" + annotation (Placement(transformation(extent={{40,-60},{20,-40}}))); + Components.Fixed fixed2 + annotation (Placement(transformation(extent={{-120,-10},{-100,10}}))); + Components.SpringDamper springDamper1( + c=10000, + d=1000, + useHeatPort=true, + s_rel(fixed=true)) + annotation (Placement(transformation(extent={{150,20},{170,40}}))); + equation + + connect(mass1.flange_b, springDamper.flange_a) + annotation (Line( + points={{-40,30},{-30,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(sine1.y, force.f) annotation (Line( + points={{-99,30},{-92,30}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(force.flange, mass1.flange_a) annotation (Line( + points={{-70,30},{-60,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass1.flange_a, damper.flange_a) annotation (Line( + points={{-60,30},{-60,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(damper.flange_b, fixed1.flange) annotation (Line( + points={{-60,-20},{-60,-30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper.flange_b, mass2.flange_a) annotation (Line( + points={{-10,30},{0,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass2.flange_b, supportFriction.flange_a) annotation (Line( + points={{20,30},{30,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(supportFriction.flange_b, spring.flange_a) annotation (Line( + points={{50,30},{60,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(spring.flange_b, mass3.flange_a) annotation (Line( + points={{80,30},{90,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(mass3.flange_b, brake.flange_a) annotation (Line( + points={{110,30},{120,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(sine2.y, brake.f_normalized) annotation (Line( + points={{121,60},{130,60},{130,41}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(elastoGap.flange_b, mass1.flange_a) annotation (Line( + points={{-70,0},{-60,0},{-60,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(const.y,convection. Gc) annotation (Line( + points={{-9,-80},{0,-80},{0,-60}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(TAmbient.port,convection. fluid) annotation (Line( + points={{20,-50},{10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(elastoGap.flange_a, fixed2.flange) annotation (Line( + points={{-90,0},{-110,0}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(elastoGap.heatPort, convection.solid) annotation (Line( + points={{-90,-10},{-90,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(damper.heatPort, convection.solid) annotation (Line( + points={{-50,0},{-50,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(springDamper.heatPort, convection.solid) annotation (Line( + points={{-30,20},{-30,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(supportFriction.heatPort, convection.solid) annotation (Line( + points={{30,20},{30,0},{-30,0},{-30,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(brake.heatPort, convection.solid) annotation (Line( + points={{120,20},{120,0},{-30,0},{-30,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(massWithStopAndFriction.heatPort, convection.solid) annotation ( + Line( + points={{180,20},{180,0},{-30,0},{-30,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + connect(brake.flange_b, springDamper1.flange_a) annotation (Line( + points={{140,30},{150,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper1.flange_b, massWithStopAndFriction.flange_a) + annotation (Line( + points={{170,30},{180,30}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(springDamper1.heatPort, convection.solid) annotation (Line( + points={{150,20},{150,0},{-30,0},{-30,-50},{-10,-50}}, + color={191,0,0}, + smooth=Smooth.None)); + annotation ( Documentation(info=" +

+This model demonstrates how to model the dissipated power of a Translational model, +by enabling the heatPort of all components and connecting these heatPorts via +a convection element to the environment. The total heat flow generated by the +elements and transported to the environment +is present in variable convection.fluid. +

+"), + experiment(StopTime=2.0, Interval=0.001), + Diagram(coordinateSystem(extent={{-120,-100},{200,100}}, + preserveAspectRatio=false))); + end HeatLosses; + + package Utilities "Utility classes used by the Example models" + extends Modelica.Icons.UtilitiesPackage; + function GenerateStribeckFrictionTable + "Generate Stribeck friction table for example Friction for the SupportFriction" + extends Modelica.Icons.Function; + input Real F_prop(final unit="N.s/m", final min=0) + "Velocity dependent friction coefficient"; + input Modelica.SIunits.Force F_Coulomb + "Constant friction: Coulomb force"; + input Modelica.SIunits.Force F_Stribeck "Stribeck effect"; + input Real fexp(final unit="s/m", final min=0) "Exponential decay"; + input Real v_max "Generate table from v=0 ... v_max"; + input Integer nTable(min=2)=100 "Number of table points"; + output Real table[nTable,2] "Friction table"; + algorithm + for i in 1:nTable loop + table[i,1] :=v_max*(i - 1)/(nTable - 1); + table[i,2] :=F_Coulomb + F_prop*table[i, 1] + + F_Stribeck*exp(-fexp*table[i, 1]); + end for; + annotation (Documentation(info=" +

+Returns a table with the friction characteristic table[nTable,2] = [0, f1; ....; v_max, fn], where the first +column is the velocity v in the range 0..v_max and the second column is the friction force +according to the Stribeck curve: +

+
+  F_Coulomb + F_prop*v + F_Stribeck*exp(-fexp*v);
+
+ +")); + end GenerateStribeckFrictionTable; + annotation (Documentation(info=" +

Utility models and functions used in the Examples

+")); + end Utilities; + annotation ( + Documentation(info=" +

+This package contains example models to demonstrate the usage of the +Translational package. Open the models and +simulate them according to the provided description in the models. +

+ +")); + end Examples; + + package Components "Components for 1D translational mechanical drive trains" + extends Modelica.Icons.Package; + + model Fixed "Fixed flange" + parameter SI.Position s0=0 "Fixed offset position of housing"; + + Interfaces.Flange_b flange annotation (Placement(transformation( + origin={0,0}, + extent={{-10,10},{10,-10}}, + rotation=180))); + equation + flange.s = s0; + annotation ( + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-80,-40},{80,-40}}, color={0,0,0}), + Line(points={{80,-40},{40,-80}}, color={0,0,0}), + Line(points={{40,-40},{0,-80}}, color={0,0,0}), + Line(points={{0,-40},{-40,-80}}, color={0,0,0}), + Line(points={{-40,-40},{-80,-80}}, color={0,0,0}), + Line(points={{0,-40},{0,-10}}, color={0,0,0}), + Text( + extent={{-150,-90},{150,-130}}, + textString="%name", + lineColor={0,0,255})}), + Documentation(info=" +

+The flange of a 1D translational mechanical system fixed +at an position s0 in the housing. May be used: +

+
    +
  • to connect a compliant element, such as a spring or a damper, + between a sliding mass and the housing. +
  • to fix a rigid element, such as a sliding mass, at a specific + position. +
+ +")); + end Fixed; + + model Mass "Sliding mass with inertia" + parameter SI.Mass m(min=0, start=1) "Mass of the sliding mass"; + parameter StateSelect stateSelect=StateSelect.default + "Priority to use s and v as states" annotation(Dialog(tab="Advanced")); + extends Translational.Interfaces.PartialRigid(L=0,s(start=0, stateSelect=stateSelect)); + SI.Velocity v(start=0, stateSelect=stateSelect) + "Absolute velocity of component"; + SI.Acceleration a(start=0) "Absolute acceleration of component"; + + equation + v = der(s); + a = der(v); + m*a = flange_a.f + flange_b.f; + annotation ( + Documentation(info=" +

+Sliding mass with inertia, without friction and two rigidly connected flanges. +

+

+The sliding mass has the length L, the position coordinate s is in the middle. +Sign convention: A positive force at flange flange_a moves the sliding mass in the positive direction. +A negative force at flange flange_a moves the sliding mass to the negative direction. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-55,0}}, color={0,127,0}), + Line(points={{55,0},{100,0}}, color={0,127,0}), + Rectangle( + extent={{-55,-30},{56,30}}, + lineColor={0,0,0}, + fillPattern=FillPattern.Sphere, + fillColor={255,255,255}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Text( + extent={{-150,85},{150,45}}, + textString="%name", + lineColor={0,0,255}), + Text( + extent={{-150,-45},{150,-75}}, + lineColor={0,0,0}, + textString="m=%m")}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-55,0}}, color={0,127,0}), + Line(points={{55,0},{100,0}}, color={0,127,0}), + Rectangle( + extent={{-55,-30},{55,30}}, + lineColor={0,0,0}, + fillPattern=FillPattern.Sphere, + fillColor={255,255,255}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Line(points={{-100,-29},{-100,-61}}, color={0,0,0}), + Line(points={{100,-61},{100,-28}}, color={0,0,0}), + Line(points={{-98,-60},{98,-60}}, color={0,0,0}), + Polygon( + points={{-101,-60},{-96,-59},{-96,-61},{-101,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Polygon( + points={{100,-60},{95,-61},{95,-59},{100,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Text( + extent={{-44,-41},{51,-57}}, + textString="Length L", + lineColor={0,0,255}), + Line(points={{0,30},{0,53}}, color={0,0,0}), + Line(points={{-72,40},{1,40}}, color={0,0,0}), + Polygon( + points={{-7,42},{-7,38},{-1,40},{-7,42}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Text( + extent={{-61,53},{-9,42}}, + textString="Position s", + lineColor={0,0,255})})); + end Mass; + + model Rod "Rod without inertia" + extends Translational.Interfaces.PartialRigid; + + equation + 0 = flange_a.f + flange_b.f; + annotation ( + Documentation(info=" +

+Rod without inertia and two rigidly connected flanges. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-55,0}}, color={0,127,0}), + Line(points={{53,0},{99,0}}, color={0,127,0}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Rectangle( + extent={{-55,10},{53,-10}}, + lineColor={160,160,164}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Text( + extent={{-150,80},{150,40}}, + textString="%name", + lineColor={0,0,255}), + Text( + extent={{-150,-30},{150,-60}}, + lineColor={0,0,0}, + textString="L=%L")}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-55,0}}, color={0,127,0}), + Line(points={{54,0},{100,0}}, color={0,127,0}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Rectangle( + extent={{-55,3},{53,-4}}, + lineColor={160,160,164}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{-100,-29},{-100,-61}}, color={0,0,0}), + Line(points={{100,-61},{100,-28}}, color={0,0,0}), + Line(points={{-98,-60},{98,-60}}, color={0,0,0}), + Polygon( + points={{-101,-60},{-96,-59},{-96,-61},{-101,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Polygon( + points={{100,-60},{95,-61},{95,-59},{100,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Text( + extent={{-44,-41},{51,-57}}, + textString="Length L", + lineColor={0,0,255})})); + end Rod; + + model Spring "Linear 1D translational spring" + extends Translational.Interfaces.PartialCompliant; + parameter SI.TranslationalSpringConstant c(final min=0, start = 1) + "Spring constant"; + parameter SI.Distance s_rel0=0 "Unstretched spring length"; + + equation + f = c*(s_rel - s_rel0); + annotation ( + Documentation(info=" +

+A linear 1D translational spring. The component can be connected either +between two sliding masses, or between +a sliding mass and the housing (model Fixed), to describe +a coupling of the sliding mass with the housing via a spring. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{-150,90},{150,50}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{-98,0},{-60,0},{-44,-30},{-16,30},{14,-30},{44,30},{ + 60,0},{100,0}},color={0,0,0}), + Text( + extent={{-150,-45},{150,-75}}, + lineColor={0,0,0}, + textString="c=%c")}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-100,65}}, color={128,128,128}), + Line(points={{100,0},{100,65}}, color={128,128,128}), + Line(points={{-100,60},{100,60}}, color={128,128,128}), + Polygon( + points={{90,63},{100,60},{90,57},{90,63}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{-56,66},{36,81}}, + lineColor={0,0,255}, + textString="s_rel"), + Line(points={{-86,0},{-60,0},{-44,-30},{-16,30},{14,-30},{44,30},{ + 60,0},{84,0}}, color={0,0,0})})); + end Spring; + + model Damper "Linear 1D translational damper" + extends Translational.Interfaces.PartialCompliantWithRelativeStates; + parameter SI.TranslationalDampingConstant d(final min=0, start = 0) + "Damping constant"; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + equation + f = d*v_rel; + lossPower = f*v_rel; + annotation ( + Documentation(info=" +

+Linear, velocity dependent damper element. It can be either connected +between a sliding mass and the housing (model Fixed), or +between two sliding masses. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-90,0},{-60,0}}, color={0,0,0}), + Line(points={{-60,-30},{-60,30}}, color={0,0,0}), + Line(points={{-60,-30},{60,-30}}, color={0,0,0}), + Line(points={{-60,30},{60,30}}, color={0,0,0}), + Rectangle( + extent={{-60,30},{30,-30}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{30,0},{90,0}}, color={0,0,0}), + Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-90},{20,-90}}, color={0,0,0}), + Text( + extent={{-150,90},{150,50}}, + textString="%name", + lineColor={0,0,255}), + Text( + extent={{-150,-45},{150,-75}}, + lineColor={0,0,0}, + textString="d=%d"), + Line(visible=useHeatPort, + points={{-100,-100},{-100,-20},{-14,-20}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-90,0},{-60,0}}, color={0,0,0}), + Line(points={{-60,-30},{-60,30}}, color={0,0,0}), + Line(points={{-60,-30},{60,-30}}, color={0,0,0}), + Line(points={{-60,30},{60,30}}, color={0,0,0}), + Rectangle( + extent={{-60,30},{30,-30}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{30,0},{90,0}}, color={0,0,0}), + Line(points={{-50,60},{50,60}}, color={128,128,128}), + Polygon( + points={{50,63},{60,60},{50,57},{50,63}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{-58,68},{42,78}}, + lineColor={128,128,128}, + textString="der(s_rel)")})); + end Damper; + + model SpringDamper "Linear 1D translational spring and damper in parallel" + extends Translational.Interfaces.PartialCompliantWithRelativeStates; + parameter SI.TranslationalSpringConstant c(final min=0, start = 1) + "Spring constant"; + parameter SI.TranslationalDampingConstant d(final min=0, start = 1) + "Damping constant"; + parameter SI.Position s_rel0=0 "Unstretched spring length"; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + protected + Modelica.SIunits.Force f_c "Spring force"; + Modelica.SIunits.Force f_d "Damping force"; + equation + f_c = c*(s_rel - s_rel0); + f_d = d*v_rel; + f = f_c + f_d; + lossPower = f_d*v_rel; + annotation ( + Documentation(info=" +

+A spring and damper element connected in parallel. +The component can be +connected either between two sliding masses to describe the elasticity +and damping, or between a sliding mass and the housing (model Fixed), +to describe a coupling of the sliding mass with the housing via a spring/damper. +

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-80,40},{-60,40},{-45,10},{-15,70},{15,10},{45,70},{ + 60,40},{80,40}}, color={0,0,0}), + Line(points={{-80,40},{-80,-70}}, color={0,0,0}), + Line(points={{-80,-70},{-52,-70}}, color={0,0,0}), + Rectangle( + extent={{-52,-49},{38,-91}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{-52,-49},{68,-49}}, color={0,0,0}), + Line(points={{-51,-91},{69,-91}}, color={0,0,0}), + Line(points={{38,-70},{80,-70}}, color={0,0,0}), + Line(points={{80,40},{80,-70}}, color={0,0,0}), + Line(points={{-90,0},{-80,0}}, color={0,0,0}), + Line(points={{80,0},{90,0}}, color={0,0,0}), + Polygon( + points={{53,-18},{23,-8},{23,-28},{53,-18}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-57,-18},{23,-18}}, color={0,0,0}), + Text( + extent={{-150,120},{150,80}}, + textString="%name", + lineColor={0,0,255}), + Text( + extent={{-150,-135},{150,-165}}, + lineColor={0,0,0}, + textString="d=%d"), + Text( + extent={{-150,-100},{150,-130}}, + lineColor={0,0,0}, + textString="c=%c"), + Line(visible=useHeatPort, + points={{-100,-100},{-100,-80},{-5,-80}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line( + points={{-80,32},{-58,32},{-43,2},{-13,62},{17,2},{47,62},{62,32}, + {80,32}}, + color={0,0,0}, + thickness=0.5), + Line(points={{-100,31},{-100,96}}, color={128,128,128}), + Line(points={{100,29},{100,94}}, color={128,128,128}), + Line(points={{-98,82},{100,82}}, color={128,128,128}), + Polygon( + points={{90,85},{100,82},{90,79},{90,85}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{-63,83},{46,103}}, + lineColor={0,0,255}, + textString="s_rel"), + Rectangle( + extent={{-52,-28},{38,-72}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{-51,-72},{69,-72}}, color={0,0,0}), + Line(points={{-52,-28},{68,-28}}, color={0,0,0}), + Line(points={{38,-50},{80,-50}}, color={0,0,0}), + Line(points={{-80,-50},{-52,-50}}, color={0,0,0}), + Line(points={{-80,32},{-80,-50}}, color={0,0,0}), + Line(points={{80,32},{80,-50}}, color={0,0,0}), + Line(points={{-90,0},{-80,0}}, color={0,0,0}), + Line(points={{90,0},{80,0}}, color={0,0,0})})); + end SpringDamper; + + model ElastoGap "1D translational spring damper combination with gap" + extends + Modelica.Mechanics.Translational.Interfaces.PartialCompliantWithRelativeStates; + parameter SI.TranslationalSpringConstant c(final min=0, start=1) + "Spring constant"; + parameter SI.TranslationalDampingConstant d(final min=0, start=1) + "Damping constant"; + parameter SI.Position s_rel0=0 "Unstretched spring length"; + parameter Real n(final min=1) = 1 + "Exponent of spring force ( f_c = -c*|s_rel-s_rel0|^n )"; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + + /* +Please note that initialization might fail due to the nonlinear spring characteristic +(spring force is zero for s_rel > s_rel0) +if a positive force is acting on the element and no other force balances this force +(e.g., when setting both initial velocity and acceleration to 0) +*/ + Boolean contact "=true, if contact, otherwise no contact"; + protected + Modelica.SIunits.Force f_c "Spring force"; + Modelica.SIunits.Force f_d2 "Linear damping force"; + Modelica.SIunits.Force f_d + "Linear damping force which is limited by spring force (|f_d| <= |f_c|)"; + equation + // Modify contact force, so that it is only "pushing" and not + // "pulling/sticking" and that it is continuous + contact = s_rel < s_rel0; + f_c = smooth(1, noEvent( if contact then -c*abs(s_rel - s_rel0)^n else 0)); + f_d2 = if contact then d*v_rel else 0; + f_d = smooth(0, noEvent( if contact then (if f_d2 < f_c then f_c else + if f_d2 > -f_c then -f_c else f_d2) else 0)); + f = f_c + f_d; + lossPower = f_d*v_rel; + annotation ( + Documentation(info=" +

+This component models a spring damper combination that can lift off. +It can be connected between a sliding mass and the housing (model +Fixed), +to describe the contact of a sliding mass with the housing. +

+ +

+As long as s_rel > s_rel0, no force is exerted (s_rel = flange_b.s - flange_a.s). +If s_rel ≤ s_rel0, the contact force is basically computed with a linear +spring/damper characteristic. With parameter n≥1 (exponent of spring force), +a nonlinear spring force can be modeled: +

+ +
+   desiredContactForce = c*|s_rel - s_rel0|^n + d*der(s_rel)
+
+ +

+Note, Hertzian contact is described by: +

+
    +
  • Contact between two metallic spheres: n=1.5
  • +
  • Contact between two metallic plates: n=1
  • +
+ +

+The above force law leads to the following difficulties: +

+ +
    +
  1. If the damper force becomes larger as the spring force and with opposite sign, + the contact force would be \"pulling/sticking\" which is unphysical, since during + contact only pushing forces can occur.
  2. + +
  3. When contact occurs with a non-zero relative speed (which is the usual + situation), the damping force has a non-zero value and therefore the contact + force changes discontinuously at s_rel = s_rel0. Again, this is not physical + because the force can only change continuously. (Note, this component is not an + idealized model where a steep characteristic is approximated by a discontinuity, + but it shall model the steep characteristic.)
  4. +
+ +

+In the literature there are several proposals to fix problem (2). Especially, often +the following model is used (see, e.g., +Lankarani, Nikravesh: Continuous Contact Force Models for Impact +Analysis in Multibody Systems, Nonlinear Dynamics 5, pp. 193-207, 1994, +pdf-download): +

+ +
+   f = c*s_rel^n + (d*s_rel^n)*der(s_rel)
+
+ +

+However, this and other models proposed in literature violate +issue (1), i.e., unphysical pulling forces can occur (if d*der(s_rel) +becomes large enough). Note, if the force law is of the form \"f = f_c + f_d\", then a +necessary condition is that |f_d| ≤ |f_c|, otherwise (1) and (2) are violated. +For this reason, the most simplest approach is used in the ElastoGap model +to fix both problems by using this necessary condition in the force law directly. +If s_rel0 = 0, the equations are: +

+ +
+    if s_rel ≥ 0 then
+       f = 0;    // contact force
+    else
+       f_c  = -c*|s_rel|^n;          // contact spring force (Hertzian contact force)
+       f_d2 = d*der(s_rel);         // linear contact damper force
+       f_d  = if f_d2 <  f_c then  f_c else
+              if f_d2 > -f_c then -f_c else f_d2;  // bounded damper force
+       f    = f_c + f_d;            // contact force
+    end if;
+
+ +

+Note, since |f_d| ≤ |f_c|, pulling forces cannot occur and the contact force +is always continuous, especially around the start of the penetration at s_rel = s_rel0. +

+ +

+In the next figure, a typical simulation with the ElastoGap model is shown +(Examples.ElastoGap) +where the different effects are visualized: +

+ +
    +
  1. Curve 1 (elastoGap1.f) is the unmodified contact force, i.e., the linear spring/damper + characteristic. A pulling/sticking force is present at the end of the contact.
  2. +
  3. Curve 2 (elastoGap2.f) is the contact force, where the force is explicitly set to + zero when pulling/sticking occurs. The contact force is discontinuous when contact starts.
  4. +
  5. Curve 3 (elastoGap3.f) is the ElastoGap model of this library. No discontinuity and no + pulling/sticking occurs.
  6. +
+ +

+ +

+"), Diagram(coordinateSystem( + preserveAspectRatio=false, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,0},{-50,0}}, color={0,127,0}), + Line( + points={{-48,34},{-48,-46}}, + color={0,0,0}, + thickness=1), + Line(points={{8,40},{8,2}}, color={0,0,0}), + Line(points={{-2,0},{38,0},{38,44},{-2,44}}, color={0,0,0}), + Line(points={{38,22},{72,22}}, color={0,0,0}), + Line( + points={{-12,-38},{-12,20}}, + color={0,0,0}, + thickness=1), + Line(points={{-12,22},{8,22}}, color={0,0,0}), + Line(points={{-12,-38},{-2,-38}}, color={0,0,0}), + Line(points={{72,0},{100,0}}, color={0,127,0}), + Line(points={{72,22},{72,-42}}, color={0,0,0}), + Line(points={{-2,-38},{10,-28},{22,-48},{38,-28},{50,-48},{64,-28}, + {72,-40}}, color={0,0,0}), + Rectangle( + extent={{8,44},{38,0}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Text( + extent={{-64,-80},{64,-64}}, + lineColor={0,0,255}, + textString="s_rel"), + Line(points={{-100,-29},{-100,-61}}, color={0,0,0}), + Line(points={{100,-61},{100,-28}}, color={0,0,0}), + Line(points={{-98,-60},{98,-60}}, color={0,0,0}), + Polygon( + points={{-101,-60},{-96,-59},{-96,-61},{-101,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Polygon( + points={{100,-60},{95,-61},{95,-59},{100,-60}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid)}), + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-98,0},{-48,0}}, color={0,127,0}), + Line( + points={{-48,38},{-48,-38}}, + color={0,0,0}, + thickness=1), + Line(points={{8,-10},{8,-48}}, + color={0,0,0}), + Line(points={{-2,-50},{38,-50},{38,-6},{-2,-6}}, + color={0,0,0}), + Line(points={{38,-28},{72,-28}}, + color={0,0,0}), + Line( + points={{-12,-38},{-12,36}}, + color={0,0,0}, + thickness=1), + Line(points={{-12,-28},{8,-28}}, + color={0,0,0}), + Line(points={{-12,24},{-6,24}}, color={0,0,0}), + Line(points={{72,0},{98,0}}, color={0,127,0}), + Line(points={{72,22},{72,-42}}, color={0,0,0}), + Line(points={{-6,24},{6,34},{18,14},{34,34},{46,14},{60,34},{68,22}}, + color={0,0,0}), + Rectangle( + extent={{8,-6},{38,-50}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Line(points={{-52,-70},{28,-70}}, color={0,0,0}), + Polygon( + points={{58,-70},{28,-60},{28,-80},{58,-70}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{-150,100},{150,60}}, + textString="%name", + lineColor={0,0,255}, + pattern=LinePattern.Dot), + Text( + extent={{-150,-125},{150,-95}}, + lineColor={0,0,0}, + textString="c=%c"), + Text( + extent={{-150,-160},{150,-130}}, + lineColor={0,0,0}, + textString="d=%d"), + Line(points={{68,22},{72,22}}, color={0,0,0}), + Line(visible=useHeatPort, + points={{-100,-100},{-100,-44},{22,-44},{22,-28}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)})); + end ElastoGap; + + model SupportFriction "Coulomb friction in support" + + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryTwoFlangesAndSupport2; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + + parameter Real f_pos[:, 2]=[0, 1] + "[v, f] Positive sliding friction characteristic (v>=0)"; + parameter Real peak(final min=1) = 1 + "peak*f_pos[1,2] = Maximum friction force for v==0"; + extends Translational.Interfaces.PartialFriction; + + SI.Position s; + SI.Force f "Friction force"; + SI.Velocity v "Absolute velocity of flange_a and flange_b"; + SI.Acceleration a "Absolute acceleration of flange_a and flange_b"; + equation + // Constant auxiliary variables + f0 = Modelica.Math.tempInterpol1(0, f_pos, 2); + f0_max = peak*f0; + free = false; + + s = flange_a.s - s_support; + flange_a.s = flange_b.s; + + // velocity and acceleration of flanges + v = der(s); + a = der(v); + v_relfric = v; + a_relfric = a; + + // Friction force + flange_a.f + flange_b.f - f = 0; + + // Friction force + f = if locked then sa*unitForce else + (if startForward then Modelica.Math.tempInterpol1( v, f_pos, 2) else + if startBackward then -Modelica.Math.tempInterpol1(-v, f_pos, 2) else + if pre(mode) == Forward then Modelica.Math.tempInterpol1( v, f_pos, 2) else + -Modelica.Math.tempInterpol1(-v, f_pos, 2)); + + lossPower = f*v_relfric; + annotation ( + Documentation(info=" +

+This element describes Coulomb friction in support, +i.e., a frictional force acting between a flange and the housing. +The positive sliding friction force \"f\" has to be defined +by table \"f_pos\" as function of the absolute velocity \"v\". +E.g. +

+
+       v |   f
+      ---+-----
+       0 |   0
+       1 |   2
+       2 |   5
+       3 |   8
+
+

+gives the following table: +

+
+   f_pos = [0, 0; 1, 2; 2, 5; 3, 8];
+
+

+Currently, only linear interpolation in the table is supported. +Outside of the table, extrapolation through the last +two table entries is used. It is assumed that the negative +sliding friction force has the same characteristic with negative +values. Friction is modelled in the following way: +

+

+When the absolute velocity \"v\" is not zero, the friction force +is a function of v and of a constant normal force. This dependency +is defined via table f_pos and can be determined by measurements, +e.g., by driving the gear with constant velocity and measuring the +needed driving force (= friction force). +

+

+When the absolute velocity becomes zero, the elements +connected by the friction element become stuck, i.e., the absolute +position remains constant. In this phase the friction force is +calculated from a force balance due to the requirement, that +the absolute acceleration shall be zero. The elements begin +to slide when the friction force exceeds a threshold value, +called the maximum static friction force, computed via: +

+
+   maximum_static_friction = peak * sliding_friction(v=0)  (peak >= 1)
+
+

+This procedure is implemented in a \"clean\" way by state events and +leads to continuous/discrete systems of equations if friction elements +are dynamically coupled which have to be solved by appropriate +numerical methods. The method is described in: +

+
+
Otter M., Elmqvist H., and Mattsson S.E. (1999): +
Hybrid Modeling in Modelica based on the Synchronous + Data Flow Principle. CACSD'99, Aug. 22.-26, Hawaii. +
+

+More precise friction models take into account the elasticity of the +material when the two elements are \"stuck\", as well as other effects, +like hysteresis. This has the advantage that the friction element can +be completely described by a differential equation without events. The +drawback is that the system becomes stiff (about 10-20 times slower +simulation) and that more material constants have to be supplied which +requires more sophisticated identification. For more details, see the +following references, especially (Armstrong and Canudas de Witt 1996): +

+
+
Armstrong B. (1991): +
Control of Machines with Friction. Kluwer Academic + Press, Boston MA.

+
Armstrong B., and Canudas de Wit C. (1996): +
Friction Modeling and Compensation. + The Control Handbook, edited by W.S.Levine, CRC Press, + pp. 1369-1382.

+
Canudas de Wit C., Olsson H., Astroem K.J., and Lischinsky P. (1995): +
A new model for control of systems with friction. + IEEE Transactions on Automatic Control, Vol. 40, No. 3, pp. 419-425.

+
+ +"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100,100}}), + graphics={ + Rectangle( + extent={{-90,10},{90,-10}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Ellipse( + extent={{-48,-10},{-28,-30}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Ellipse( + extent={{-10,-10},{10,-30}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Ellipse( + extent={{30,-10},{50,-30}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Polygon( + points={{-60,-30},{60,-30},{60,-12},{80,-12},{80,-50},{-80,-50},{ + -80,-12},{-60,-12},{-60,-30}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Solid, + smooth=Smooth.None, + fillColor={175,175,175}), + Text( + extent={{-150,100},{150,60}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{-10,-85},{-5,-80}}, color={0,0,0}), + Line(points={{-5,-90},{5,-80}}, color={0,0,0}), + Line(points={{-10,-90},{0,-80}}, color={0,0,0}), + Line(points={{0,-90},{10,-80}}, color={0,0,0}), + Polygon( + points={{-60,-50},{-20,-80},{20,-80},{60,-50},{-60,-50}}, + lineColor={95,95,95}, + smooth=Smooth.None, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid), + Ellipse( + extent={{-50,30},{-30,10}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Ellipse( + extent={{-10,30},{10,10}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Ellipse( + extent={{30,30},{50,10}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Sphere, + fillColor={175,175,175}), + Polygon( + points={{-60,30},{60,30},{60,12},{80,12},{80,50},{-80,50},{-80,12}, + {-60,12},{-60,30}}, + lineColor={95,95,95}, + fillPattern=FillPattern.Solid, + smooth=Smooth.None, + fillColor={175,175,175}), + Line(visible=useHeatPort, + points={{-100,-100},{-100,-20},{0,-20}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)})); + end SupportFriction; + + model Brake "Brake based on Coulomb friction" + + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryTwoFlangesAndSupport2; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + parameter Real mue_pos[:, 2]=[0, 0.5] + "[v, f] Positive sliding friction characteristic (v>=0)"; + parameter Real peak(final min=1) = 1 + "peak*mue_pos[1,2] = Maximum friction force for v==0"; + parameter Real cgeo(final min=0) = 1 + "Geometry constant containing friction distribution assumption"; + parameter SI.Force fn_max(final min=0, start=1) "Maximum normal force"; + extends Translational.Interfaces.PartialFriction; + + SI.Position s; + SI.Force f "Brake friction force"; + SI.Velocity v "Absolute velocity of flange_a and flange_b"; + SI.Acceleration a "Absolute acceleration of flange_a and flange_b"; + + Real mue0 "Friction coefficient for v=0 and forward sliding"; + SI.Force fn "Normal force (=fn_max*f_normalized)"; + + // Constant auxiliary variable + Modelica.Blocks.Interfaces.RealInput f_normalized + "Normalized force signal 0..1 (normal force = fn_max*f_normalized; brake is active if > 0)" + annotation (Placement(transformation( + origin={0,110}, + extent={{20,-20},{-20,20}}, + rotation=90))); + equation + mue0 = Modelica.Math.tempInterpol1(0, mue_pos, 2); + + s = s_a; + s = s_b; + + // velocity and acceleration of flanges flange_a and flange_b + v = der(s); + a = der(v); + v_relfric = v; + a_relfric = a; + + // Friction force, normal force and friction force for v_rel=0 + flange_a.f + flange_b.f - f = 0; + fn = fn_max*f_normalized; + f0 = mue0*cgeo*fn; + f0_max = peak*f0; + free = fn <= 0; + + // Friction force + f = if locked then sa*unitForce else + if free then 0 else + cgeo*fn*(if startForward then Modelica.Math.tempInterpol1( v, mue_pos, 2) else + if startBackward then -Modelica.Math.tempInterpol1(-v, mue_pos, 2) else + if pre(mode) == Forward then Modelica.Math.tempInterpol1( v, mue_pos, 2) else + -Modelica.Math.tempInterpol1(-v, mue_pos, 2)); + + lossPower = f*v_relfric; + annotation ( + Documentation(info=" +

+This component models a brake, i.e., a component where a frictional +force is acting between the housing and a flange and a controlled normal +force presses the flange to the housing in order to increase friction. +The normal force fn has to be provided as input signal f_normalized in a normalized form +(0 ≤ f_normalized ≤ 1), +fn = fn_max*f_normalized, where fn_max has to be provided as parameter. +Friction in the brake is modelled in the following way: +

+

+When the absolute velocity \"v\" is not zero, the friction force +is a function of the velocity dependent friction coefficient mue(v) , of +the normal force \"fn\", and of a geometry constant \"cgeo\" which takes into +account the geometry of the device and the assumptions on the friction +distributions: +

+
+        frictional_force = cgeo * mue(v) * fn
+
+

+ Typical values of coefficients of friction: +

+
+      dry operation   :  mue = 0.2 .. 0.4
+      operating in oil:  mue = 0.05 .. 0.1
+
+

+ The positive part of the friction characteristic mue(v), + v >= 0, is defined via table mue_pos (first column = v, + second column = mue). Currently, only linear interpolation in + the table is supported. +

+

+ When the absolute velocity becomes zero, the elements + connected by the friction element become stuck, i.e., the absolute + position remains constant. In this phase the friction force is + calculated from a force balance due to the requirement, that + the absolute acceleration shall be zero. The elements begin + to slide when the friction force exceeds a threshold value, + called the maximum static friction force, computed via: +

+
+       frictional_force = peak * cgeo * mue(w=0) * fn   (peak >= 1)
+
+

+This procedure is implemented in a \"clean\" way by state events and +leads to continuous/discrete systems of equations if friction elements +are dynamically coupled. The method is described in: +

+
+
Otter M., Elmqvist H., and Mattsson S.E. (1999): +
Hybrid Modeling in Modelica based on the Synchronous + Data Flow Principle. CACSD'99, Aug. 22.-26, Hawaii. +
+

+More precise friction models take into account the elasticity of the +material when the two elements are \"stuck\", as well as other effects, +like hysteresis. This has the advantage that the friction element can +be completely described by a differential equation without events. The +drawback is that the system becomes stiff (about 10-20 times slower +simulation) and that more material constants have to be supplied which +requires more sophisticated identification. For more details, see the +following references, especially (Armstrong and Canudas de Witt 1996): +

+
+
Armstrong B. (1991): +
Control of Machines with Friction. Kluwer Academic + Press, Boston MA.

+
Armstrong B., and Canudas de Wit C. (1996): +
Friction Modeling and Compensation. + The Control Handbook, edited by W.S.Levine, CRC Press, + pp. 1369-1382.

+
Canudas de Wit C., Olsson H., Astroem K.J., and Lischinsky P. (1995): +
A new model for control of systems with friction. + IEEE Transactions on Automatic Control, Vol. 40, No. 3, pp. 419-425.

+
+"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100,100}}), + graphics={ + Rectangle( + extent={{-90,10},{90,-10}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{-20,30},{20,20}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{-20,-20},{20,-30}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Polygon( + points={{0,-30},{10,-50},{-10,-50},{0,-30}}, + lineColor={0,0,127}, + fillColor={0,0,127}, + fillPattern=FillPattern.Solid), + Polygon( + points={{10,50},{-10,50},{0,30},{10,50}}, + lineColor={0,0,127}, + fillColor={0,0,127}, + fillPattern=FillPattern.Solid), + Line( + points={{0,90},{0,50}}, + color={0,0,0}, + smooth=Smooth.None), + Rectangle( + extent={{20,28},{30,22}}, + lineColor={175,175,175}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{20,-22},{30,-28}}, + lineColor={175,175,175}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{30,28},{36,-102}}, + lineColor={175,175,175}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{14,-96},{30,-102}}, + lineColor={175,175,175}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid), + Line( + points={{0,-50},{0,-60},{-40,-50},{-40,48},{0,60},{0,90}}, + color={0,0,0}, + smooth=Smooth.None), + Text( + extent={{-150,-120},{150,-160}}, + textString="%name", + lineColor={0,0,255}), + Line(visible=useHeatPort, + points={{-100,-102},{-100,-16},{0,-16}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)})); + end Brake; + + model IdealGearR2T + "Gearbox transforming rotational into translational motion" + extends Modelica.Mechanics.Rotational.Components.IdealGearR2T; + annotation (Documentation(info=" +

Couples rotational and translational motion, like a toothed wheel with a toothed rack, specifying the ratio of rotational / translational motion.

+")); + end IdealGearR2T; + + model IdealRollingWheel + "Simple 1-dim. model of an ideal rolling wheel without inertia" + extends Modelica.Mechanics.Rotational.Components.IdealRollingWheel; + annotation (Documentation(info=" +

Couples rotational and translational motion, like an ideal rolling wheel, specifying the wheel radius.

+")); + end IdealRollingWheel; + + model InitializeFlange + "Initializes a flange with pre-defined position, speed and acceleration (usually, this is reference data from a control bus)" + extends Modelica.Blocks.Icons.Block; + parameter Boolean use_s_start = true + "= true, if initial position is defined by input s_start, otherwise not initialized"; + parameter Boolean use_v_start = true + "= true, if initial speed is defined by input v_start, otherwise not initialized"; + parameter Boolean use_a_start = true + "= true, if initial acceleration is defined by input a_start, otherwise not initialized"; + + parameter StateSelect stateSelect=StateSelect.default + "Priority to use flange angle and speed as states"; + + Modelica.Blocks.Interfaces.RealInput s_start(unit="m") if use_s_start + "Initial position of flange" + annotation (Placement(transformation(extent={{-140,40},{-100,80}}, + rotation=0))); + Modelica.Blocks.Interfaces.RealInput v_start(unit="m/s") if use_v_start + "Initial speed of flange" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}, + rotation=0))); + Modelica.Blocks.Interfaces.RealInput a_start(unit="m/s2") if use_a_start + "Initial angular acceleration of flange" + annotation (Placement(transformation(extent={{-140,-80},{-100,-40}}, + rotation=0))); + Interfaces.Flange_b flange "Flange that is initialized" annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + + Modelica.SIunits.Position s_flange(stateSelect=stateSelect)=flange.s + "Flange position"; + Modelica.SIunits.Velocity v_flange(stateSelect=stateSelect)= der(s_flange) + "= der(s_flange)"; + + protected + encapsulated model Set_s_start "Set s_start" + import Modelica; + extends Modelica.Blocks.Icons.Block; + Modelica.Blocks.Interfaces.RealInput s_start(unit="m") "Start position" + annotation (HideResult=true, Placement(transformation(extent={{-140,-20},{ + -100,20}}, rotation=0))); + + Modelica.Mechanics.Translational.Interfaces.Flange_b flange + annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + initial equation + flange.s = s_start; + equation + flange.f = 0; + + end Set_s_start; + + encapsulated model Set_v_start "Set v_start" + import Modelica; + extends Modelica.Blocks.Icons.Block; + Modelica.Blocks.Interfaces.RealInput v_start(unit="m/s") "Start velocity" + annotation (HideResult=true, Placement(transformation(extent={{-140,-20},{ + -100,20}}, rotation=0))); + + Modelica.Mechanics.Translational.Interfaces.Flange_b flange + annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + initial equation + der(flange.s) = v_start; + equation + flange.f = 0; + + end Set_v_start; + + encapsulated model Set_a_start "Set a_start" + import Modelica; + extends Modelica.Blocks.Icons.Block; + Modelica.Blocks.Interfaces.RealInput a_start(unit="m/s2") "Start acceleration" + annotation (HideResult=true, Placement(transformation(extent={{-140,-20},{ + -100,20}}, rotation=0))); + + Modelica.Mechanics.Translational.Interfaces.Flange_b flange(s(stateSelect=StateSelect.avoid)) + annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + Modelica.SIunits.Velocity v = der(flange.s) annotation(HideResult=true); + initial equation + der(v) = a_start; + equation + flange.f = 0; + + end Set_a_start; + + encapsulated model Set_flange_f "Set flange_f to zero" + import Modelica; + extends Modelica.Blocks.Icons.Block; + Modelica.Mechanics.Translational.Interfaces.Flange_b flange + annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + equation + flange.f = 0; + end Set_flange_f; + protected + Set_s_start set_s_start if use_s_start annotation (Placement( + transformation(extent={{-20,50},{0,70}}, rotation=0))); + Set_v_start set_v_start if use_v_start + annotation (Placement(transformation(extent={{-20, + -10},{0,10}}, rotation=0))); + Set_a_start set_a_start if use_a_start + annotation (Placement(transformation(extent={{-20, + -70},{0,-50}}, rotation=0))); + Set_flange_f set_flange_f annotation (Placement(transformation(extent={ + {20,-100},{40,-80}}, rotation=0))); + equation + connect(set_s_start.flange, flange) annotation (Line( + points={{0,60},{60,60},{60,0},{100,0}}, + color={0,0,0}, + smooth=Smooth.None)); + connect(set_v_start.flange, flange) annotation (Line( + points={{0,0},{100,0}}, + color={0,0,0}, + smooth=Smooth.None)); + connect(set_a_start.flange, flange) annotation (Line( + points={{0,-60},{60,-60},{60,0},{100,0}}, + color={0,0,0}, + smooth=Smooth.None)); + connect(set_flange_f.flange, flange) annotation (Line( + points={{40,-90},{60,-90},{60,0},{100,0}}, + color={0,0,0}, + smooth=Smooth.None)); + connect(s_start, set_s_start.s_start) annotation (Line( + points={{-120,60},{-22,60}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(v_start, set_v_start.v_start) annotation (Line( + points={{-120,0},{-22,0}}, + color={0,0,127}, + smooth=Smooth.None)); + connect(a_start, set_a_start.a_start) annotation (Line( + points={{-120,-60},{-22,-60}}, + color={0,0,127}, + smooth=Smooth.None)); + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={ + Text( + extent={{-94,74},{68,46}}, + lineColor={0,0,0}, + textString="s_start"), + Text( + extent={{-94,16},{70,-14}}, + lineColor={0,0,0}, + textString="v_start"), + Text( + extent={{-94,-46},{66,-74}}, + lineColor={0,0,0}, + textString="a_start")}), + Documentation(info=" +

+This component is used to optionally initialize the position, speed, +and/or acceleration of the flange to which this component +is connected. Via parameters use_s_start, use_v_start, use_a_start +the corresponding input signals s_start, v_start, a_start are conditionally +activated. If an input is activated, the corresponding flange property +is initialized with the input value at start time. +

+ +

+For example, if \"use_s_start = true\", then flange.s is initialized +with the value of the input signal \"s_start\" at the start time. +

+ +

+Additionally, it is optionally possible to define the \"StateSelect\" +attribute of the flange position and the flange speed via parameter +\"stateSelection\". +

+ +

+This component is especially useful when the initial values of a flange +shall be set according to reference signals of a controller that are +provided via a signal bus. +

+ +")); + end InitializeFlange; + + model MassWithStopAndFriction + "Sliding mass with hard stop and Stribeck friction" + extends PartialFrictionWithStop; + SI.Velocity v(start=0, stateSelect = StateSelect.always) + "Absolute velocity of flange_a and flange_b"; + SI.Acceleration a(start=0) + "Absolute acceleration of flange_a and flange_b"; + parameter Modelica.SIunits.Mass m(start=1) "Mass"; + parameter Real F_prop(final unit="N.s/m", final min=0, start = 1) + "Velocity dependent friction"; + parameter Modelica.SIunits.Force F_Coulomb(start=5) + "Constant friction: Coulomb force"; + parameter Modelica.SIunits.Force F_Stribeck(start=10) "Stribeck effect"; + parameter Real fexp(final unit="s/m", final min=0, start = 2) + "Exponential decay"; + extends + Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT; + Integer stopped; + encapsulated partial model PartialFrictionWithStop + "Base model of Coulomb friction elements with stop" + + import SI = Modelica.SIunits; + import Modelica.Mechanics.Translational.Interfaces.PartialRigid; + parameter SI.Position smax(start= 25) + "Right stop for (right end of) sliding mass"; + parameter SI.Position smin(start=-25) + "Left stop for (left end of) sliding mass"; + parameter SI.Velocity v_small=1e-3 + "Relative velocity near to zero (see model info text)" + annotation(Dialog(tab="Advanced")); + // Equations to define the following variables have to be defined in subclasses + SI.Velocity v_relfric "Relative velocity between frictional surfaces"; + SI.Acceleration a_relfric + "Relative acceleration between frictional surfaces"; + SI.Force f + "Friction force (positive, if directed in opposite direction of v_rel)"; + SI.Force f0 "Friction force for v=0 and forward sliding"; + SI.Force f0_max "Maximum friction force for v=0 and locked"; + Boolean free "true, if frictional element is not active"; + // Equations to define the following variables are given in this class + Real sa(unit="1") + "Path parameter of friction characteristic f = f(a_relfric)"; + Boolean startForward(start=false, fixed=true) + "= true, if v_rel=0 and start of forward sliding or v_rel > v_small"; + Boolean startBackward(start=false, fixed=true) + "= true, if v_rel=0 and start of backward sliding or v_rel < -v_small"; + Boolean locked(start=false) "true, if v_rel=0 and not sliding"; + extends PartialRigid(s(start=0, stateSelect = StateSelect.always)); + constant Integer Unknown=3 "Value of mode is not known"; + constant Integer Free=2 "Element is not active"; + constant Integer Forward=1 "v_rel > 0 (forward sliding)"; + constant Integer Stuck=0 + "v_rel = 0 (forward sliding, locked or backward sliding)"; + constant Integer Backward=-1 "v_rel < 0 (backward sliding)"; + Integer mode( + final min=Backward, + final max=Unknown, + start=Unknown, fixed=true); + protected + constant SI.Acceleration unitAcceleration = 1 annotation(HideResult=true); + constant SI.Force unitForce = 1 annotation(HideResult=true); + equation + /* Friction characteristic + (locked is introduced to help the Modelica translator determining + the different structural configurations, + if for each configuration special code shall be generated) +*/ + startForward = pre(mode) == Stuck and (sa > f0_max/unitForce and s < (smax - L/2) or + pre(startForward) and sa > f0/unitForce and s < (smax - L/2)) or pre(mode) + == Backward and v_relfric > v_small or initial() and (v_relfric > 0); + startBackward = pre(mode) == Stuck and (sa < -f0_max/unitForce and s > (smin + L/2) or + pre(startBackward) and sa < -f0/unitForce and s > (smin + L/2)) or pre(mode) + == Forward and v_relfric < -v_small or initial() and (v_relfric < 0); + locked = not free and + not (pre(mode) == Forward or startForward or pre(mode) == Backward or startBackward); + + a_relfric/unitAcceleration = if locked then 0 else + if free then sa else + if startForward then sa - f0_max/unitForce else + if startBackward then sa + f0_max/unitForce else + if pre(mode) == Forward then sa - f0_max/unitForce else + sa + f0_max/unitForce; + + /* Friction torque has to be defined in a subclass. Example for a clutch: + f = if locked then sa else + if free then 0 else + cgeo*fn*(if startForward then Math.tempInterpol1( v_relfric, mue_pos, 2) else + if startBackward then -Math.tempInterpol1(-v_relfric, mue_pos, 2) else + if pre(mode) == Forward then Math.tempInterpol1( v_relfric, mue_pos, 2) else + -Math.tempInterpol1(-v_relfric, mue_pos, 2)); +*/ + // finite state machine to determine configuration + mode = if free then Free else + (if (pre(mode) == Forward or pre(mode) == Free or startForward) and v_relfric > 0 and s < (smax - L/2) then + Forward else + if (pre(mode) == Backward or pre(mode) == Free or startBackward) and v_relfric < 0 and s > (smin + L/2) then + Backward else + Stuck); + annotation (Documentation(info=" +

+Basic model for Coulomb friction that models the stuck phase in a reliable way.
+Additionally, a left and right stop are handled. +

+")); + end PartialFrictionWithStop; + equation + // Constant auxiliary variables + f0 = (F_Coulomb + F_Stribeck); + f0_max = f0*1.001; + free = f0 <= 0 and F_prop <= 0 and s > smin + L/2 and s < smax - L/2; + // Velocity and acceleration of flanges + v = der(s); + a = der(v); + v_relfric = v; + a_relfric = a; + // Equilibrium of forces + 0 = flange_a.f + flange_b.f - f - m*der(v); + // Friction force + f = if locked then sa*unitForce else + if free then 0 else + (if startForward then F_prop*v + F_Coulomb + F_Stribeck else + if startBackward then F_prop*v - F_Coulomb - F_Stribeck else + if pre(mode) == Forward then F_prop*v + F_Coulomb + F_Stribeck*exp(-fexp*abs(v)) else + F_prop*v - F_Coulomb - F_Stribeck*exp(-fexp*abs(v))); + lossPower = f*v_relfric; + equation + when (initial()) then + assert(s > smin + L/2 or s >= smin + L/2 and v >= 0, + "Error in initialization of hard stop. (s - L/2) must be >= smin\n"+ + "(s=" + String(s) + ", L=" + String(L) + ", smin=" + String(smin) + ")"); + assert(s < smax - L/2 or s <= smax - L/2 and v <= 0, + "Error in initialization of hard stop. (s + L/2) must be <= smax\n"+ + "(s=" + String(s) + ", L=" + String(L) + ", smax=" + String(smax) + ")"); + end when; + + // Define events for hard stops and reinitialize the state variables velocity v and position s + stopped = if s <= smin + L/2 then -1 else if s >= smax - L/2 then +1 else 0; + when stopped <> 0 then + reinit(s, if stopped < 0 then smin + L/2 else smax - L/2); + reinit(v, 0); + end when; + /* +Version 1: + + when not (s < smax - L/2) then + reinit(s, smax - L/2); + if (not initial() or v>0) then + reinit(v, 0); + end if; + end when; + + when not (s > smin + L/2) then + reinit(s, smin + L/2); + if (not initial() or v<0) then + reinit(v, 0); + end if; + end when; + +Version 2: + stopped := if s <= smin + L/2 then -1 else if s >= smax - L/2 then +1 else 0; + when (initial()) then + assert(s > smin + L/2 or s >= smin + L/2 and v >= 0, + "Error in initialization of hard stop. (s - L/2) must be >= smin\n"+ + "(s=" + String(s) + ", L=" + String(L) + ", smin=" + String(smin) + ")"); + assert(s < smax - L/2 or s <= smax - L/2 and v <= 0, + "Error in initialization of hard stop. (s + L/2) must be <= smax\n"+ + "(s=" + String(s) + ", L=" + String(L) + ", smax=" + String(smax) + ")"); + end when; + when stopped <> 0 then + reinit(s, if stopped < 0 then smin + L/2 else smax - L/2); + if (not initial() or stopped*v>0) then + reinit(v, 0); + end if; + end when; +*/ + annotation ( + Documentation(info=" +

This element describes the Stribeck friction characteristics of a sliding mass, +i. e. the frictional force acting between the sliding mass and the support. Included is a +hard stop for the position.

+

+The surface is fixed and there is friction between sliding mass and surface. +The frictional force f is given for positive velocity v by: +

+
+f = F_Coulomb + F_prop * v + F_Stribeck * exp (-fexp * v)
+
+ +

+ +

+ +

+The distance between the left and the right connector is given by parameter L. +The position of the center of gravity, coordinate s, is in the middle between +the two flanges.

+

+There are hard stops at smax and smin, i. e. if +flange_a.s >= smin and flange_b.s <= xmax the sliding mass can move freely.

+

When the absolute velocity becomes zero, the sliding mass becomes stuck, i.e., the absolute position remains constant. In this phase the +friction force is calculated from a force balance due to the requirement that the +absolute acceleration shall be zero. The elements begin to slide when the friction +force exceeds a threshold value, called the maximum static friction force, computed via:

+
+   maximum_static_friction =  F_Coulomb + F_Stribeck
+
+

+ This requires the states Stop.s and Stop.v . If these states are eliminated during the index reduction +the model will not work. To avoid this any inertias should be connected via springs +to the Stop element, other sliding masses, dampers or hydraulic chambers must be avoided.

+

For more details of the used friction model see the following reference:

+ +
+
Beater P. (1999):
+
+Entwurf hydraulischer Maschinen. Springer Verlag Berlin Heidelberg New York.
+
+ +

The friction model is implemented in a \"clean\" way by state events and leads to +continuous/discrete systems of equations which have to be solved by appropriate +numerical methods. The method is described in:

+ +
+
Otter M., Elmqvist H., and Mattsson S.E. (1999):
+
Hybrid Modeling in Modelica based on the Synchronous Data Flow Principle. + CACSD'99, Aug. 22.-26, Hawaii.
+
+ +

More precise friction models take into account the elasticity of the material when +the two elements are \"stuck\", as well as other effects, like hysteresis. This has +the advantage that the friction element can be completely described by a differential +equation without events. The drawback is that the system becomes stiff (about 10-20 times +slower simulation) and that more material constants have to be supplied which requires more +sophisticated identification. For more details, see the following references, especially +(Armstrong and Canudas de Witt 1996):

+
+
+Armstrong B. (1991):
+
Control of Machines with Friction. Kluwer Academic Press, Boston MA.
+
+
Armstrong B., and Canudas de Wit C. (1996):
+
Friction Modeling and Compensation. The Control Handbook, edited by W.S.Levine, CRC Press, pp. 1369-1382.
+
+
Canudas de Wit C., Olsson H., Astroem K.J., and Lischinsky P. (1995):
+
A new model for control of systems with friction. IEEE Transactions on Automatic Control, Vol. 40, No. 3, pp. 419-425.
+
+
+ +

Optional heatPort

+

+The dissipated energy is transported in form of heat to the optional heatPort connector +that can be enabled via parameter \"useHeatPort\". Independently whether the heatPort is +or is not enabled, the dissipated power is defined with variable \"lossPower\". +If contact occurs at the hard stops, the lossPower is not correctly modelled +at this time instant, because the hard stop would introduce a Dirac impulse +in the lossPower due to the discontinuously changing kinetic energy of the mass +(lossPower is the derivative of the kinetic energy at the time instant of the impact). +

+ +", revisions=" +

Release Notes:

+
    +
  • First Version from December 7, 1999 by P. Beater (based on Rotational.BearingFriction)
  • +
  • July 14, 2001 by P. Beater, assert on initialization added, diagram modified
  • +
  • October 11, 2001, by Hans Olsson, Dassault Systèmes AB, modified assert to handle start at stops, +modified event logic such if you have friction parameters equal to zero you do not get events +between the stops.
  • +
  • June 10, 2002 by P. Beater, StateSelect.always for variables s and v (instead of fixed=true).
  • +
+"), + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Polygon( + points={{80,-100},{50,-90},{50,-110},{80,-100}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-30,-100},{50,-100}}, color={0,0,0}), + Rectangle( + extent={{-30,30},{35,-35}}, + lineColor={0,0,0}, + fillPattern=FillPattern.Sphere, + fillColor={255,255,255}), + Line(points={{-90,0},{-30,0}}, color={0,127,0}), + Rectangle( + extent={{-70,-45},{74,-60}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{-63,-15},{-55,-45}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{60,-16},{69,-45}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line(points={{35,0},{90,0}}, color={0,127,0}), + Text( + extent={{-150,80},{150,40}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{-50,-90},{-30,-70}}, color={0,0,0}), + Line(points={{-30,-70},{30,-70}}, color={0,0,0}), + Line(points={{-30,-90},{-10,-70}}, color={0,0,0}), + Line(points={{-10,-90},{10,-70}}, color={0,0,0}), + Line(points={{10,-90},{30,-70}}, color={0,0,0}), + Text( + extent={{-150,-110},{150,-140}}, + lineColor={0,0,0}, + textString="m=%m"), + Line(visible=useHeatPort, + points={{-100,-100},{-100,-40},{3,-40}}, + color={191,0,0}, + pattern=LinePattern.Dot, + smooth=Smooth.None)}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Polygon( + points={{50,-75},{20,-65},{20,-85},{50,-75}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-60,-75},{20,-75}}, color={0,0,0}), + Rectangle( + extent={{-30,26},{35,-9}}, + lineColor={0,0,0}, + fillPattern=FillPattern.Sphere, + fillColor={255,255,255}), + Line(points={{-90,0},{-30,0}}, color={0,127,0}), + Line(points={{35,0},{90,0}}, color={0,127,0}), + Rectangle( + extent={{-68,-14},{76,-29}}, + lineColor={0,0,0}, + fillColor={192,192,192}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{-119,43},{-111,17}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line( + points={{-111,43},{-111,50}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Line( + points={{-151,49},{-113,49}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Text( + extent={{-149,51},{-126,60}}, + textString="s min", + lineColor={0,0,255}), + Polygon( + points={{-121,52},{-111,49},{-121,46},{-121,52}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Rectangle( + extent={{124,42},{132,17}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line( + points={{124,39},{124,87}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Line( + points={{-19,78},{121,78}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Text( + extent={{-17,83},{6,92}}, + textString="s max", + lineColor={0,0,255}), + Polygon( + points={{114,81},{124,78},{114,75},{114,81}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line( + points={{5,26},{5,63}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Line( + points={{-77,58},{-1,58}}, + color={0,0,0}, + pattern=LinePattern.Solid, + thickness=0.25, + arrow={Arrow.None,Arrow.None}), + Text( + extent={{-75,60},{-38,71}}, + textString="Position s", + lineColor={0,0,255}), + Polygon( + points={{-5,61},{5,58},{-5,55},{-5,61}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line(points={{-100,-10},{-100,-60}}, color={0,0,0}), + Line(points={{100,-10},{100,-60}}, color={0,0,0}), + Polygon( + points={{90,-47},{100,-50},{90,-53},{90,-47}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Polygon( + points={{-90,-47},{-90,-53},{-100,-50},{-90,-47}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Line(points={{-90,-50},{92,-50}}, color={0,0,0}), + Text( + extent={{-11,-46},{26,-36}}, + textString="Length L", + lineColor={0,0,255})})); + end MassWithStopAndFriction; + + model RelativeStates "Definition of relative state variables" + extends Translational.Interfaces.PartialTwoFlanges; + parameter StateSelect stateSelect=StateSelect.prefer + "Priority to use the relative angle and relative speed as states"; + SI.Position s_rel(start=0, stateSelect=StateSelect.prefer) + "Relative position used as state variable"; + SI.Velocity v_rel(start=0, stateSelect=StateSelect.prefer) + "Relative velocity used as state variable"; + SI.Acceleration a_rel(start=0) "Relative angular acceleration"; + + equation + s_rel = flange_b.s - flange_a.s; + v_rel = der(s_rel); + a_rel = der(v_rel); + flange_a.f = 0; + flange_b.f = 0; + annotation ( + Documentation(info=" +

+Usually, the absolute position and the absolute velocity of +Modelica.Mechanics.Translational.Inertia models are used as state variables. +In some circumstances, relative quantities are better suited, e.g., +because it may be easier to supply initial values. +In such cases, model RelativeStates allows the definition of state variables +in the following way: +

+
    +
  • Connect an instance of this model between two flange connectors.
  • +
  • The relative position and the relative velocity + between the two connectors are used as state variables. +
+

+An example is given in the next figure +

+ +

+\"relativeStates2\" +

+ +

+Here, the relative position and the relative velocity between +the two masses are used as state variables. Additionally, the +simulator selects either the absolute position and absolute +velocity of model mass1 or of model mass2 as state variables. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Ellipse( + extent={{-40,40},{40,-40}}, + lineColor={0,255,255}, + fillColor={0,255,255}, + fillPattern=FillPattern.Solid), + Text( + extent={{-40,40},{40,-40}}, + textString="S", + lineColor={0,0,255}), + Line( + points={{-92,0},{-42,0}}, + color={0,0,0}, + pattern=LinePattern.Dot), + Line( + points={{40,0},{90,0}}, + color={0,0,0}, + pattern=LinePattern.Dot), + Text( + extent={{-150,90},{150,50}}, + textString="%name", + lineColor={0,0,255})}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Ellipse( + extent={{-40,40},{40,-40}}, + lineColor={0,255,255}, + fillColor={0,255,255}, + fillPattern=FillPattern.Solid), + Text( + extent={{-40,40},{40,-40}}, + textString="S", + lineColor={0,0,255}), + Line( + points={{40,0},{90,0}}, + color={0,0,0}, + pattern=LinePattern.Dash), + Line(points={{-100,-10},{-100,-80}}, color={160,160,164}), + Line(points={{100,-10},{100,-80}}, color={160,160,164}), + Polygon( + points={{80,-65},{80,-55},{100,-60},{80,-65}}, + lineColor={160,160,164}, + fillColor={160,160,164}, + fillPattern=FillPattern.Solid), + Line(points={{-100,-60},{80,-60}}, color={160,160,164}), + Text( + extent={{-30,-70},{30,-90}}, + textString="w_rel", + lineColor={0,0,255}), + Line(points={{-76,80},{-5,80}}, color={128,128,128}), + Polygon( + points={{14,80},{-6,85},{-6,75},{14,80}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Text( + extent={{18,87},{86,74}}, + lineColor={128,128,128}, + textString="moving direction"), + Line( + points={{-90,0},{-40,0}}, + color={0,0,0}, + pattern=LinePattern.Dash)})); + end RelativeStates; + annotation (Icon(coordinateSystem(preserveAspectRatio = true, extent = {{-100,-100},{100,100}}), graphics = { + Rectangle( + origin = {11.5,31.183}, + lineColor = {64,64,64}, + fillColor = {255,255,255}, + fillPattern = FillPattern.Sphere, + extent = {{-67,-66},{44,-6}})}), Documentation(info=" +

+This package contains basic components 1D mechanical translational drive trains. +

+")); + end Components; + + package Sensors "Sensors for 1-dim. translational mechanical quantities" + + extends Modelica.Icons.SensorsPackage; + + model PositionSensor "Ideal sensor to measure the absolute position" + extends Translational.Interfaces.PartialAbsoluteSensor; + Modelica.Blocks.Interfaces.RealOutput s(unit="m") + "Absolute position of flange as output signal" + annotation (Placement(transformation(extent={{100,-11}, + {120,9}}, rotation=0), iconTransformation(extent={{100, + -10},{120,10}}))); + + equation + s = flange.s; + annotation ( + Documentation(info=" +

+Measures the absolute position s of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Text( + extent={{80,-28},{114,-62}}, + lineColor={0,0,0}, + textString="s")})); + end PositionSensor; + + model SpeedSensor "Ideal sensor to measure the absolute velocity" + extends Translational.Interfaces.PartialAbsoluteSensor; + Modelica.Blocks.Interfaces.RealOutput v(unit="m/s") + "Absolute velocity of flange as output signal" + annotation (Placement(transformation(extent={{100,-10},{120,10}}, + rotation=0))); + + equation + v = der(flange.s); + annotation ( + Documentation(info=" +

+Measures the absolute velocity v of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Text( + extent={{80,-28},{111,-61}}, + lineColor={0,0,0}, + textString="v")})); + end SpeedSensor; + + model AccSensor "Ideal sensor to measure the absolute acceleration" + extends Translational.Interfaces.PartialAbsoluteSensor; + SI.Velocity v "Absolute velocity of flange"; + Modelica.Blocks.Interfaces.RealOutput a(unit="m/s2") + "Absolute acceleration of flange as output signal" + annotation (Placement(transformation(extent={{100,-10},{120,10}}, + rotation=0))); + + equation + v = der(flange.s); + a = der(v); + annotation ( + Documentation(info=" +

+Measures the absolute acceleration a +of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Text( + extent={{80,-28},{115,-60}}, + lineColor={0,0,0}, + textString="a")})); + end AccSensor; + + model RelPositionSensor "Ideal sensor to measure the relative position" + extends Translational.Interfaces.PartialRelativeSensor; + Modelica.Blocks.Interfaces.RealOutput s_rel(unit="m") + "Distance between two flanges (= flange_b.s - flange_a.s) as output signal" + annotation (Placement(transformation(extent={{-10,-10}, + {10,10}}, rotation=270, + origin={0,-110}))); + + equation + s_rel = flange_b.s - flange_a.s; + 0 = flange_a.f; + annotation ( + Documentation(info=" +

+Measures the relative position s of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70.4,0},{100,0}}, color={0,0,127}), + Text( + extent={{8,-68},{42,-102}}, + lineColor={0,0,0}, + textString="s"), + Line(points={{0,-99},{0,-60}}, color={0,0,127})})); + end RelPositionSensor; + + model RelSpeedSensor "Ideal sensor to measure the relative speed" + extends Translational.Interfaces.PartialRelativeSensor; + SI.Position s_rel + "Distance between the two flanges (flange_b.s - flange_a.s)"; + Modelica.Blocks.Interfaces.RealOutput v_rel(unit="m/s") + "Relative velocity between two flanges (= der(flange_b.s) - der(flange_a.s)) as output signal" + annotation (Placement(transformation(extent={{-10,-10}, + {10,10}}, rotation=270, + origin={0,-110}))); + + equation + s_rel = flange_b.s - flange_a.s; + v_rel = der(s_rel); + 0 = flange_a.f; + annotation ( + Documentation(info=" +

+Measures the relative speed v of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +", revisions= + " +

Release Notes:

+
    +
  • First Version from August 26, 1999 by P. Beater
  • +
+"), + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70.4,0},{100,0}}, color={0,0,127}), + Text( + extent={{8,-68},{42,-102}}, + lineColor={0,0,0}, + textString="v"), + Line(points={{0,-100},{0,-61}}, color={0,0,127})})); + end RelSpeedSensor; + + model RelAccSensor "Ideal sensor to measure the relative acceleration" + extends Translational.Interfaces.PartialRelativeSensor; + SI.Position s_rel + "Distance between the two flanges (flange_b.s - flange_a.s)"; + SI.Velocity v_rel + "Relative velocity between the two flanges (der(flange_b.s) - der(flange_a.s))"; + Modelica.Blocks.Interfaces.RealOutput a_rel(unit="m/s2") + "Relative acceleration between two flanges (= der(v_rel)) as output signal" + annotation (Placement(transformation(extent={{-10,-10}, + {10,10}}, rotation=270, + origin={0,-110}))); + + equation + s_rel = flange_b.s - flange_a.s; + v_rel = der(s_rel); + a_rel = der(v_rel); + 0 = flange_a.f; + annotation ( + Documentation(info=" +

+Measures the relative acceleration a of a flange in an ideal way and provides the result as +output signals (to be further processed with blocks of the +Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70.4,0},{100,0}}, color={0,0,127}), + Text( + extent={{7,-68},{41,-102}}, + lineColor={0,0,0}, + textString="a"), + Line(points={{0,-99},{0,-60}}, color={0,0,127})})); + end RelAccSensor; + + model ForceSensor "Ideal sensor to measure the force between two flanges" + extends Translational.Interfaces.PartialRelativeSensor; + Modelica.Blocks.Interfaces.RealOutput f(unit="N") + "Force in flange_a and flange_b (f = flange_a.f = -flange_b.f) as output signal" + annotation (Placement(transformation( + origin={-80,-110}, + extent={{10,-10},{-10,10}}, + rotation=90))); + equation + flange_a.s = flange_b.s; + flange_a.f = f; + annotation ( + Documentation(info=" +

+Measures the cut-force between two flanges in an ideal way +and provides the result as output signal (to be further processed +with blocks of the Modelica.Blocks library). +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-40,-70},{40,-120}}, + lineColor={0,0,0}, + textString="f"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Line(points={{-80,-100},{-80,0}}, color={0,0,127})})); + end ForceSensor; + + model PowerSensor + "Ideal sensor to measure the power between two flanges (= flange_a.f*der(flange_a.s))" + extends Translational.Interfaces.PartialRelativeSensor; + Modelica.Blocks.Interfaces.RealOutput power(unit="W") + "Power in flange flange_a as output signal" + annotation (Placement(transformation( + origin={-80,-110}, + extent={{10,-10},{-10,10}}, + rotation=90))); + equation + flange_a.s = flange_b.s; + power = flange_a.f*der(flange_a.s); + annotation ( + Documentation(info=" +

+Measures the power between two flanges in an ideal way +and provides the result as output signal power +(to be further processed with blocks of the Modelica.Blocks library). +

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-75,-79},{67,-119}}, + lineColor={0,0,0}, + textString="power"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Line(points={{-80,-100},{-80,0}}, color={0,0,127})})); + end PowerSensor; + + model MultiSensor + "Ideal sensor to measure the absolute velocity, force and power between two flanges" + extends Translational.Interfaces.PartialRelativeSensor; + Modelica.Blocks.Interfaces.RealOutput power(unit="W") + "Power in flange flange_a as output signal" + annotation (Placement(transformation( + origin={-60,-110}, + extent={{10,-10},{-10,10}}, + rotation=90))); + Modelica.Blocks.Interfaces.RealOutput f(unit="N") + "Force in flange_a and flange_b (f = flange_a.f = -flange_b.f) as output signal" + annotation (Placement(transformation( + extent={{10,-10},{-10,10}}, + rotation=90, + origin={0,-110}))); + Modelica.Blocks.Interfaces.RealOutput v(unit="m/s") + "Absolute velocity of flange as output signal as output signal" + annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=-90, + origin={60,-110}))); + equation + flange_a.s = flange_b.s; + f = flange_a.f; + v = der(flange_a.s); + power = f*v; + + annotation ( + Documentation(info=" +

+Measures the absolute velocity of a flange_a, the cut-force and power between two flanges in an +ideal way and provides the results as output signals v, f and power, respectively.

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-146,-70},{-56,-100}}, + lineColor={0,0,0}, + textString="power"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Line(points={{-60,-100},{-60,-60}}, + color={0,0,127}), + Text( + extent={{-28,-71},{52,-101}}, + lineColor={0,0,0}, + textString="f"), + Line(points={{0,-100},{0,-60}}, color={0,0,127}), + Line(points={{60,-100},{60,-60}}, color={0,0,127}), + Text( + extent={{60,-70},{114,-101}}, + lineColor={0,0,0}, + textString="v")})); + end MultiSensor; + annotation ( + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100, + 100}}), graphics={ + Line(points={{-56,-61},{-56,-81}}, color={0,0,0}), + Line(points={{-36,-61},{-36,-81}}, color={0,0,0}), + Line(points={{-16,-61},{-16,-81}}, color={0,0,0}), + Line(points={{4,-61},{4,-81}}, color={0,0,0}), + Line(points={{24,-61},{24,-81}}, color={0,0,0}), + Line(points={{44,-61},{44,-81}}, color={0,0,0})}), + Documentation(info=" +

+This package contains ideal sensor components that provide +the connector variables as signals for further processing with the +Modelica.Blocks library. +

+")); + end Sensors; + + package Sources "Sources to drive 1D translational mechanical components" + extends Modelica.Icons.SourcesPackage; + + model Position + "Forced movement of a flange according to a reference position" + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryOneFlangeAndSupport2 + ( s(stateSelect=if exact then StateSelect.default else StateSelect.prefer)); + parameter Boolean exact=false + "true/false exact treatment/filtering the input signal"; + parameter SI.Frequency f_crit=50 + "if exact=false, critical frequency of filter to filter input signal" annotation(Dialog(enable=not exact)); + SI.Velocity v(start=0, stateSelect=if exact then StateSelect.default else StateSelect.prefer) + "If exact=false, absolute velocity of flange_b else dummy"; + SI.Acceleration a(start=0) + "If exact=false, absolute acceleration of flange_b else dummy"; + Modelica.Blocks.Interfaces.RealInput s_ref(unit="m") + "Reference position of flange as input signal" annotation (Placement( + transformation(extent={{-140,-20},{-100,20}}, rotation=0))); + protected + parameter Modelica.SIunits.AngularFrequency w_crit=2*Modelica.Constants.pi*f_crit + "Critical frequency"; + constant Real af=1.3617 "s coefficient of Bessel filter"; + constant Real bf=0.6180 "s*s coefficient of Bessel filter"; + + initial equation + if not exact then + s = s_ref; + end if; + equation + if exact then + s = s_ref; + v = 0; + a = 0; + else + // Filter: a = s_ref*S^2/(1 + (af/w_crit)*S + (bf/w_crit^2)*S^2) + v = der(s); + a = der(v); + a = ((s_ref - s)*w_crit - af*v)*(w_crit/bf); + end if; + annotation ( + Documentation(info=" +

+The input signal s_ref defines the reference +position in [m]. Flange flange_b is forced +to move relative to the support connector according to this reference motion. According to parameter +exact (default = false), this is done in the following way: +

    +
  1. exact=true
    + The reference position is treated exactly. This is only possible, if + the input signal is defined by an analytical function which can be + differentiated at least twice. If this prerequisite is fulfilled, + the Modelica translator will differentiate the input signal twice + in order to compute the reference acceleration of the flange.
  2. +
  3. exact=false
    + The reference position is filtered and the second derivative + of the filtered curve is used to compute the reference acceleration + of the flange. This second derivative is not computed by + numerical differentiation but by an appropriate realization of the + filter. For filtering, a second order Bessel filter is used. + The critical frequency (also called cut-off frequency) of the + filter is defined via parameter f_crit in [Hz]. This value + should be selected in such a way that it is higher as the essential + low frequencies in the signal.
  4. +
+

+The input signal can be provided from one of the signal generator +blocks of the block library Modelica.Blocks.Sources. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-56,-36},{-178,-66}}, + lineColor={0,0,0}, + textString="s_ref"), + Rectangle( + extent={{-100,20},{100,-20}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Text( + extent={{150,60},{-150,100}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{0,52},{0,32}}, color={0,0,0}), + Line(points={{-29,32},{30,32}}, color={0,0,0}), + Line(points={{-30,-32},{30,-32}}, color={0,0,0}), + Line(points={{0,-32},{0,-100}}, color={0,0,0}), + Line(points={{30,-42},{20,-52}}, color={0,0,0}), + Line(points={{30,-32},{10,-52}}, color={0,0,0}), + Line(points={{20,-32},{0,-52}}, color={0,0,0}), + Line(points={{10,-32},{-10,-52}}, color={0,0,0}), + Line(points={{0,-32},{-20,-52}}, color={0,0,0}), + Line(points={{-10,-32},{-30,-52}}, color={0,0,0}), + Line(points={{-20,-32},{-30,-42}}, color={0,0,0}), + Text( + extent={{144,-30},{30,-60}}, + lineColor={0,0,0}, + textString="exact="), + Text( + extent={{134,-68},{22,-96}}, + lineColor={0,0,0}, + textString="%exact")})); + end Position; + + model Speed "Forced movement of a flange according to a reference speed" + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryOneFlangeAndSupport2 + ( s(start=0, fixed=true, stateSelect=StateSelect.prefer)); + parameter Boolean exact=false + "true/false exact treatment/filtering the input signal"; + parameter SI.Frequency f_crit=50 + "if exact=false, critical frequency of filter to filter input signal" annotation(Dialog(enable=not exact)); + SI.Velocity v(stateSelect=if exact then StateSelect.default else StateSelect.prefer) + "Absolute velocity of flange_b"; + SI.Acceleration a + "If exact=false, absolute acceleration of flange_b else dummy"; + Modelica.Blocks.Interfaces.RealInput v_ref(unit="m/s") + "Reference speed of flange as input signal" annotation (Placement( + transformation(extent={{-140,-20},{-100,20}}, rotation=0))); + + protected + parameter Modelica.SIunits.AngularFrequency w_crit=2*Modelica.Constants.pi*f_crit + "Critical frequency"; + initial equation + if not exact then + v = v_ref; + end if; + equation + v = der(s); + if exact then + v = v_ref; + a = 0; + else + // Filter: a = v_ref/(1 + (1/w_crit)*s) + a = der(v); + a = (v_ref - v)*w_crit; + end if; + annotation ( + Documentation(info=" +

+The input signal v_ref defines the reference +speed in [m/s]. Flange flange_b is forced +to move relative to the support connector according to this reference motion. According to parameter +exact (default = false), this is done in the following way: +

    +
  1. exact=true
    + The reference speed is treated exactly. This is only possible, if + the input signal is defined by an analytical function which can be + differentiated at least once. If this prerequisite is fulfilled, + the Modelica translator will differentiate the input signal once + in order to compute the reference acceleration of the flange.
  2. +
  3. exact=false
    + The reference speed is filtered and the first derivative + of the filtered curve is used to compute the reference acceleration + of the flange. This first derivative is not computed by + numerical differentiation but by an appropriate realization of the + filter. For filtering, a first order filter is used. + The critical frequency (also called cut-off frequency) of the + filter is defined via parameter f_crit in [Hz]. This value + should be selected in such a way that it is higher as the essential + low frequencies in the signal.
  4. +
+

+The input signal can be provided from one of the signal generator +blocks of the block library Modelica.Blocks.Sources. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-54,-36},{-174,-68}}, + lineColor={0,0,0}, + textString="v_ref"), + Line(points={{-30,-32},{30,-32}}, color={0,0,0}), + Line(points={{0,-32},{0,-100}}, color={0,0,0}), + Line(points={{30,-42},{20,-52}}, color={0,0,0}), + Line(points={{30,-32},{10,-52}}, color={0,0,0}), + Line(points={{20,-32},{0,-52}}, color={0,0,0}), + Line(points={{10,-32},{-10,-52}}, color={0,0,0}), + Line(points={{0,-32},{-20,-52}}, color={0,0,0}), + Line(points={{-10,-32},{-30,-52}}, color={0,0,0}), + Line(points={{-20,-32},{-30,-42}}, color={0,0,0}), + Rectangle( + extent={{-100,20},{100,-20}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Line(points={{-29,32},{30,32}}, color={0,0,0}), + Line(points={{0,52},{0,32}}, color={0,0,0}), + Text( + extent={{150,60},{-150,100}}, + textString="%name", + lineColor={0,0,255}), + Text( + extent={{146,-38},{32,-64}}, + lineColor={0,0,0}, + textString="exact="), + Text( + extent={{140,-76},{22,-102}}, + lineColor={0,0,0}, + textString="%exact")})); + end Speed; + + model Accelerate + "Forced movement of a flange according to an acceleration signal" + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryOneFlangeAndSupport2 + (s(start=0, fixed=true, stateSelect=StateSelect.prefer)); + SI.Velocity v(start=0, fixed=true, stateSelect=StateSelect.prefer) + "Absolute velocity of flange_b"; + SI.Acceleration a "Absolute acceleration of flange_b"; + + Modelica.Blocks.Interfaces.RealInput a_ref(unit="m/s2") + "Absolute acceleration of flange as input signal" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}, + rotation=0))); + + equation + v = der(s); + a = der(v); + a = a_ref; + annotation ( + Documentation(info=" +

+The input signal a in [m/s2] moves the 1D translational flange +connector flange_b with a predefined acceleration, i.e., the flange +is forced to move relative to the support connector with this acceleration. The velocity and the +position of the flange are also predefined and are determined by +integration of the acceleration. +

+

+The acceleration \"a(t)\" can be provided from one of the signal generator +blocks of the block library Modelica.Blocks.Source. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-56,-40},{-166,-68}}, + lineColor={0,0,0}, + textString="a_ref"), + Line(points={{-30,-32},{30,-32}}, color={0,0,0}), + Line(points={{0,-32},{0,-100}}, color={0,0,0}), + Line(points={{30,-42},{20,-52}}, color={0,0,0}), + Line(points={{30,-32},{10,-52}}, color={0,0,0}), + Line(points={{20,-32},{0,-52}}, color={0,0,0}), + Line(points={{10,-32},{-10,-52}}, color={0,0,0}), + Line(points={{0,-32},{-20,-52}}, color={0,0,0}), + Line(points={{-10,-32},{-30,-52}}, color={0,0,0}), + Line(points={{-20,-32},{-30,-42}}, color={0,0,0}), + Rectangle( + extent={{-100,20},{100,-20}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Line(points={{-29,32},{30,32}}, color={0,0,0}), + Line(points={{0,52},{0,32}}, color={0,0,0}), + Text( + extent={{150,60},{-150,100}}, + textString="%name", + lineColor={0,0,255})})); + end Accelerate; + + model Move + "Forced movement of a flange according to a position, velocity and acceleration signal" + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryOneFlangeAndSupport2; + Modelica.Blocks.Interfaces.RealInput u[3] + "Position, velocity and acceleration of flange as input signals" + annotation (Placement(transformation(extent={{-140,-20},{-100,20}}, + rotation=0))); + protected + function position + extends Modelica.Icons.Function; + input Real q_qd_qdd[3] + "Required values for position, speed, acceleration"; + input Real dummy + "Just to have one input signal that should be differentiated to avoid possible problems in the Modelica tool (is not used)"; + output Real q; + algorithm + q :=q_qd_qdd[1]; + annotation (derivative(noDerivative=q_qd_qdd) = position_der, + InlineAfterIndexReduction=true); + end position; + + function position_der + extends Modelica.Icons.Function; + input Real q_qd_qdd[3] + "Required values for position, speed, acceleration"; + input Real dummy + "Just to have one input signal that should be differentiated to avoid possible problems in the Modelica tool (is not used)"; + input Real dummy_der; + output Real qd; + algorithm + qd :=q_qd_qdd[2]; + annotation (derivative(noDerivative=q_qd_qdd, order=2) = position_der2, + InlineAfterIndexReduction=true); + end position_der; + + function position_der2 + extends Modelica.Icons.Function; + input Real q_qd_qdd[3] + "Required values for position, speed, acceleration"; + input Real dummy + "Just to have one input signal that should be differentiated to avoid possible problems in the Modelica tool (is not used)"; + input Real dummy_der; + input Real dummy_der2; + output Real qdd; + algorithm + qdd :=q_qd_qdd[3]; + end position_der2; + equation + s = position(u,time); + annotation ( + Documentation(info=" +

+Flange flange_b is forced to move relative to the support connector with a predefined motion +according to the input signals: +

+
+    u[1]: position of flange
+    u[2]: velocity of flange
+    u[3]: acceleration of flange
+
+

+The user has to guarantee that the input signals are consistent to each other, +i.e., that u[2] is the derivative of u[1] and that +u[3] is the derivative of u. There are, however, +also applications where by purpose these conditions do not hold. For example, +if only the position dependent terms of a mechanical system shall be +calculated, one may provide position = position(t) and set the velocity +and the acceleration to zero. +

+

+The input signals can be provided from one of the signal generator +blocks of the block library Modelica.Blocks.Sources. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-192,-38},{-32,-70}}, + lineColor={0,0,0}, + textString="s,v,a"), + Line(points={{-30,-32},{30,-32}}, color={0,0,0}), + Line(points={{0,-32},{0,-100}}, color={0,0,0}), + Line(points={{30,-42},{20,-52}}, color={0,0,0}), + Line(points={{30,-32},{10,-52}}, color={0,0,0}), + Line(points={{20,-32},{0,-52}}, color={0,0,0}), + Line(points={{10,-32},{-10,-52}}, color={0,0,0}), + Line(points={{0,-32},{-20,-52}}, color={0,0,0}), + Line(points={{-10,-32},{-30,-52}}, color={0,0,0}), + Line(points={{-20,-32},{-30,-42}}, color={0,0,0}), + Rectangle( + extent={{-100,20},{100,-20}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Line(points={{0,52},{0,32}}, color={0,0,0}), + Line(points={{-29,32},{30,32}}, color={0,0,0}), + Text( + extent={{150,60},{-150,100}}, + textString="%name", + lineColor={0,0,255})})); + end Move; + + model Force + "External force acting on a drive train element as input signal" + extends + Modelica.Mechanics.Translational.Interfaces.PartialElementaryOneFlangeAndSupport2; + Modelica.Blocks.Interfaces.RealInput f(unit="N") "Driving force as input signal" + annotation (Placement(transformation( + extent={{-140,-20},{-100,20}}, rotation=0))); + + equation + flange.f = -f; + annotation ( + Documentation(info=" +

+The input signal \"f\" in [N] characterizes an external +force which acts (with positive sign) at a flange, +i.e., the component connected to the flange is driven by force f. +

+

+Input signal f can be provided from one of the signal generator +blocks of Modelica.Blocks.Source. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Polygon( + points={{-100,10},{20,10},{20,41},{90,0},{20,-41},{20,-10},{-100, + -10},{-100,10}}, + lineColor={0,127,0}, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Text( + extent={{-150,-32},{-80,-62}}, + lineColor={0,0,0}, + textString="f"), + Text( + extent={{-150,90},{150,50}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{-30,-60},{30,-60}}, color={0,0,0}), + Line(points={{0,-60},{0,-101}}, color={0,0,0}), + Line(points={{-30,-80},{-10,-60}}, color={0,0,0}), + Line(points={{-10,-80},{10,-60}}, color={0,0,0}), + Line(points={{10,-80},{30,-60}}, color={0,0,0}), + Polygon( + points={{-61,-50},{-30,-40},{-30,-60},{-61,-50}}, + lineColor={0,0,0}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-31,-50},{50,-50}}, color={0,0,0}), + Line(points={{-50,-80},{-30,-60}}, color={0,0,0})})); + end Force; + + model Force2 "Input signal acting as torque on two flanges" + extends Translational.Interfaces.PartialTwoFlanges; + Modelica.Blocks.Interfaces.RealInput f(unit="N") "Driving force as input signal" + annotation (Placement(transformation( + extent={{-20,-20},{20,20}}, rotation=270, + origin={0,60}), iconTransformation( + extent={{-20,-20},{20,20}}, + rotation=270, + origin={0,40}))); + + equation + flange_a.f = f; + flange_b.f = -f; + annotation ( + Documentation(info=" +

+The input signal \"f\" in [N] characterizes an external +force which acts (with positive sign) at both flanges, +i.e., the components connected to these flanges are driven by force f. +

+

+Input signal s can be provided from one of the signal generator +blocks of Modelica.Blocks.Source. +

+ +"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Text( + extent={{-150,-40},{150,-80}}, + textString="%name", + lineColor={0,0,255}), + Polygon( + points={{90,0},{60,-30},{60,-10},{10,-10},{10,10},{60,10},{60,31}, + {90,0}}, + lineColor={0,127,0}, + smooth=Smooth.None, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid), + Polygon( + points={{-90,0},{-60,30},{-60,10},{-10,10},{-10,-10},{-60,-10},{-60, + -30},{-90,0}}, + lineColor={0,127,0}, + smooth=Smooth.None, + fillColor={215,215,215}, + fillPattern=FillPattern.Solid)})); + end Force2; + + model LinearSpeedDependentForce "Linear dependency of force versus speed" + extends Modelica.Mechanics.Translational.Interfaces.PartialForce; + parameter Modelica.SIunits.Force f_nominal + "Nominal force (if negative, force is acting as load)"; + parameter Boolean ForceDirection=true + "Same direction of force in both directions of movement"; + parameter Modelica.SIunits.Velocity v_nominal(min=Modelica.Constants.eps) + "Nominal speed"; + Modelica.SIunits.Velocity v + "Velocity of flange with respect to support (= der(s))"; + + equation + v = der(s); + if ForceDirection then + f = -f_nominal*abs(v/v_nominal); + else + f = -f_nominal*(v/v_nominal); + end if; + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={Line(points={{-100,-100},{100,100}}, + color={0,0,255})}), Documentation(info=" +

+Model of force, linearly dependent on velocity of flange.
+Parameter ForceDirection chooses whether direction of force is the same in both directions of movement or not. +

+")); + end LinearSpeedDependentForce; + + model QuadraticSpeedDependentForce + "Quadratic dependency of force versus speed" + extends Modelica.Mechanics.Translational.Interfaces.PartialForce; + parameter Modelica.SIunits.Force f_nominal + "Nominal force (if negative, force is acting as load)"; + parameter Boolean ForceDirection=true + "Same direction of force in both directions of movement"; + parameter Modelica.SIunits.Velocity v_nominal(min=Modelica.Constants.eps) + "Nominal speed"; + Modelica.SIunits.Velocity v + "Velocity of flange with respect to support (= der(s))"; + equation + v = der(s); + if ForceDirection then + f = -f_nominal*(v/v_nominal)^2; + else + f = -f_nominal*smooth(1, if v >= 0 then (v/v_nominal)^2 else -(v/v_nominal)^2); + end if; + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,-100},{-80,-98},{-60,-92},{-40,-82},{-20,-68},{0,-50},{20,-28},{40,-2},{60,28},{80,62},{100,100}}, + color={0,0,127}, + smooth=Smooth.Bezier)}),Documentation(info=" +

+Model of force, quadratic dependent on velocity of flange.
+Parameter ForceDirection chooses whether direction of force is the same in both directions of movement or not. +

+")); + end QuadraticSpeedDependentForce; + + model ConstantForce "Constant force, not dependent on speed" + extends Modelica.Mechanics.Translational.Interfaces.PartialForce; + parameter Modelica.SIunits.Force f_constant + "Nominal force (if negative, force is acting as load)"; + equation + f = -f_constant; + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={Line(points={{-100,0},{98,0}}, + color={0,0,255}), Text( + extent={{-118,58},{126,34}}, + lineColor={0,0,0}, + textString="%f_constant")}), + Documentation(info=" +

+Model of constant force, not dependent on velocity of flange.
+Positive force acts accelerating. +

+")); + end ConstantForce; + + model ConstantSpeed "Constant speed, not dependent on force" + extends Modelica.Mechanics.Translational.Interfaces.PartialForce; + parameter Modelica.SIunits.Velocity v_fixed + "Fixed speed (if negative, force is acting as load)"; + Modelica.SIunits.Velocity v + "Velocity of flange with respect to support (= der(s))"; + equation + v = der(s); + v = v_fixed; + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={Line(points={{0,-100},{0,100}}, + color={0,0,255}), Text( + extent={{-120,60},{124,36}}, + lineColor={0,0,0}, + textString="%v_fixed")}), + Documentation(info=" +

+Model of fixed velocity of flange, not dependent on force. +

+")); + end ConstantSpeed; + + model ForceStep "Constant force, not dependent on speed" + extends Modelica.Mechanics.Translational.Interfaces.PartialForce; + parameter Modelica.SIunits.Force stepForce(start=1) + "Height of force step (if negative, force is acting as load)"; + parameter Modelica.SIunits.Force offsetForce(start=0) "Offset of force"; + parameter Modelica.SIunits.Time startTime=0 + "Force = offset for time < startTime"; + equation + f = -offsetForce - (if time < startTime then 0 else stepForce); + annotation (Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={Line(points={{-80,-60},{0,-60},{0, + 60},{80,60}}, color={0,0,255}), Text( + extent={{0,-40},{100,-60}}, + lineColor={0,0,0}, + textString="time")}), Documentation(info=" +

+Model of a force step at time .
+Positive force acts accelerating. +

+")); + end ForceStep; + + annotation ( Documentation(info=" +

+This package contains ideal sources to drive 1D mechanical translational drive trains. +

+")); + end Sources; + + package Interfaces + "Interfaces for 1-dim. translational mechanical components" + extends Modelica.Icons.InterfacesPackage; + + connector Flange_a + "(left) 1D translational flange (flange axis directed INTO cut plane, e. g. from left to right)" + + SI.Position s "Absolute position of flange"; + flow SI.Force f "Cut force directed into flange"; + annotation(defaultComponentName = "flange_a", + Documentation(info=" +

+This is a flange for 1D translational mechanical systems. In the cut plane of +the flange a unit vector n, called flange axis, is defined which is directed +INTO the cut plane, i. e. from left to right. All vectors in the cut plane are +resolved with respect to +this unit vector. E.g. force f characterizes a vector which is directed in +the direction of n with value equal to f. When this flange is connected to +other 1D translational flanges, this means that the axes vectors of the connected +flanges are identical. +

+

+The following variables are transported through this connector: +

+
+  s: Absolute position of the flange in [m]. A positive translation
+     means that the flange is translated along the flange axis.
+  f: Cut-force in direction of the flange axis in [N].
+
+"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={0,127,0}, + fillColor={0,127,0}, + fillPattern=FillPattern.Solid)}), + Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100}, + {100,100}}), graphics={Rectangle( + extent={{-40,-40},{40,40}}, + lineColor={0,127,0}, + fillColor={0,127,0}, + fillPattern=FillPattern.Solid), Text( + extent={{-160,110},{40,50}}, + lineColor={0,127,0}, + textString="%name")})); + end Flange_a; + + connector Flange_b + "(right) 1D translational flange (flange axis directed OUT OF cut plane)" + + SI.Position s "Absolute position of flange"; + flow SI.Force f "Cut force directed into flange"; + annotation(defaultComponentName = "flange_b", + Documentation(info=" +

+This is a flange for 1D translational mechanical systems. In the cut plane of +the flange a unit vector n, called flange axis, is defined which is directed +OUT OF the cut plane. All vectors in the cut plane are resolved with respect to +this unit vector. E.g. force f characterizes a vector which is directed in +the direction of n with value equal to f. When this flange is connected to +other 1D translational flanges, this means that the axes vectors of the connected +flanges are identical. +

+

+The following variables are transported through this connector: +

+  s: Absolute position of the flange in [m]. A positive translation
+     means that the flange is translated along the flange axis.
+  f: Cut-force in direction of the flange axis in [N].
+
+"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100,100}}), graphics={ + Rectangle( + extent={{-100,-100},{100,100}}, + lineColor={0,127,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid)}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Rectangle( + extent={{-40,-40},{40,40}}, + lineColor={0,127,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), Text( + extent={{-40,110},{160,50}}, + lineColor={0,127,0}, + textString="%name")})); + end Flange_b; + + connector Support "Support/housing 1D translational flange" + + SI.Position s "Absolute position of flange"; + flow SI.Force f "Cut force directed into flange"; + annotation (Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100, + -100},{100,100}}), graphics={ + Rectangle( + extent={{-60,60},{60,-60}}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid, + pattern=LinePattern.None), + Text( + extent={{-160,110},{40,50}}, + lineColor={0,127,0}, + textString="%name"), + Rectangle( + extent={{-40,-40},{40,40}}, + lineColor={0,127,0}, + fillColor={0,127,0}, + fillPattern=FillPattern.Solid)}), Icon(coordinateSystem( + preserveAspectRatio=true, extent={{-100,-100},{100,100}}), + graphics={Rectangle( + extent={{-150,150},{150,-150}}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid, + pattern=LinePattern.None), Rectangle( + extent={{-90,-90},{90,90}}, + lineColor={0,127,0}, + fillColor={0,127,0}, + fillPattern=FillPattern.Solid)}), + Documentation(info=" +

This is a connector for 1-dim. rotational mechanical systems and models the support or housing of a shaft. The following variables are defined in this connector:

+ + + + + + + + +

s

Absolute position of the support/housing in [m]

f

Reaction force in the support/housing in [N]

+


The support connector is usually defined as conditional connector. It is most convenient to utilize it

+ +")); + end Support; + + model InternalSupport + "Adapter model to utilize conditional support connector" + input SI.Force f + "External support force (must be computed via force balance in model where InternalSupport is used; = flange.f)"; + SI.Position s "External support position (= flange.s)"; + Flange_a flange + "Internal support flange (must be connected to the conditional support connector for useSupport=true and to conditional fixed model for useSupport=false)" + annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); + equation + flange.f = f; + flange.s = s; + annotation ( Icon(coordinateSystem( + preserveAspectRatio=true, extent={{-100,-100},{100,100}}), + graphics={Text( + extent={{-200,80},{200,40}}, + lineColor={0,0,255}, + textString="%name"), Rectangle( + extent={{-20,20},{20,-20}}, + lineColor={0,127,0}, + fillColor={175,175,175}, + fillPattern=FillPattern.Solid)}), + Documentation(info=" +

+This is an adapter model to utilize a conditional support connector +in an elementary component, i.e., where the component equations are +defined textually: +

+ +
    +
  • If useSupport = true, the flange has to be connected to the conditional + support connector.
  • +
  • If useSupport = false, the flange has to be connected to the conditional + fixed model.
  • +
+ +

+Variable f is defined as input and must be provided when using +this component as a modifier (computed via a force balance in +the model where InternalSupport is used). Usually, model InternalSupport is +utilized via the partial models: +

+ +
+ +PartialElementaryOneFlangeAndSupport,
+ +PartialElementaryTwoFlangesAndSupport,
+ +PartialElementaryRotationalToTranslational. +
+ +

+Note, the support position can always be accessed as internalSupport.s, and +the support force can always be accessed as internalSupport.f. +

+")); + end InternalSupport; + + partial model PartialTwoFlanges + "Component with two translational 1D flanges" + + Flange_a flange_a + "(left) driving flange (flange axis directed in to cut plane, e. g. from left to right)" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + Flange_b flange_b + "(right) driven flange (flange axis directed out of cut plane)" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + annotation ( + Documentation(info=" +

+This is a 1D translational component with two flanges. +It is used e.g., to built up parts of a drive train consisting +of several base components. +

+")); + end PartialTwoFlanges; + + partial model PartialOneFlangeAndSupport + "Partial model for a component with one translational 1-dim. shaft flange and a support used for graphical modeling, i.e., the model is build up by drag-and-drop from elementary components" + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Flange_b flange "Flange of component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, rotation=0))); + Support support if useSupport "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + protected + Support internalSupport + "Internal support/housing of component (either connected to support, if useSupport=true, or connected to fixed, if useSupport=false)" + annotation (Placement(transformation(extent={{-3,-83},{3,-77}}))); + Components.Fixed fixed if not useSupport + "Fixed support/housing, if not useSupport" + annotation (Placement(transformation(extent={{10,-94},{30,-74}}))); + equation + connect(fixed.flange, internalSupport) annotation (Line( + points={{20,-84},{20,-80},{0,-80}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(internalSupport, support) annotation (Line( + points={{0,-80},{0,-100}}, + pattern=LinePattern.None, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with one flange and a support/housing. +It is used e.g., to build up parts of a drive train graphically consisting +of several components. +

+ +

+If useSupport=true, the support connector is conditionally enabled +and needs to be connected.
+If useSupport=false, the support connector is conditionally disabled +and instead the component is internally fixed to ground. +

+ +"), Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Text( + extent={{-38,-98},{-6,-96}}, + lineColor={95,95,95}, + textString="(if useSupport)"), Text( + extent={{21,-95},{61,-96}}, + lineColor={95,95,95}, + textString="(if not useSupport)")}), + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialOneFlangeAndSupport; + + partial model PartialTwoFlangesAndSupport + "Partial model for a component with two translational 1-dim. shaft flanges and a support used for graphical modeling, i.e., the model is build up by drag-and-drop from elementary components" + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Flange_a flange_a "Flange of left end" + annotation (Placement(transformation(extent={{-110,-10}, {-90,10}}, rotation=0))); + Flange_b flange_b "Flange of right end" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, rotation=0))); + Support support if useSupport "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + protected + Support internalSupport + "Internal support/housing of component (either connected to support, if useSupport=true, or connected to fixed, if useSupport=false)" + annotation (Placement(transformation(extent={{-3,-83},{3,-77}}))); + Components.Fixed fixed if not useSupport + "Fixed support/housing, if not useSupport" + annotation (Placement(transformation(extent={{10,-97},{30,-77}}))); + equation + connect(fixed.flange, internalSupport) annotation (Line( + points={{20,-87},{20,-80},{0,-80}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(internalSupport, support) annotation (Line( + points={{0,-80},{0,-100}}, + pattern=LinePattern.None, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with two flanges and a support/housing. +It is used e.g., to build up parts of a drive train graphically consisting +of several components. +

+ +

+If useSupport=true, the support connector is conditionally enabled +and needs to be connected.
+If useSupport=false, the support connector is conditionally disabled +and instead the component is internally fixed to ground. +

+ +"), Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Text( + extent={{-38,-98},{-6,-96}}, + lineColor={95,95,95}, + textString="(if useSupport)"), Text( + extent={{24,-97},{64,-98}}, + lineColor={95,95,95}, + textString="(if not useSupport)")}), + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialTwoFlangesAndSupport; + + partial model PartialRigid + "Rigid connection of two translational 1D flanges" + SI.Position s + "Absolute position of center of component (s = flange_a.s + L/2 = flange_b.s - L/2)"; + parameter SI.Length L(start=0) + "Length of component, from left flange to right flange (= flange_b.s - flange_a.s)"; + Flange_a flange_a "Left flange of translational component" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + Flange_b flange_b "Right flange of translational component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + equation + flange_a.s = s - L/2; + flange_b.s = s + L/2; + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with two rigidly connected flanges. +The fixed distance between the left and the right flange is defined by parameter \"L\". +The forces at the right and left flange can be different. +It is used e.g., to built up sliding masses. +

+")); + end PartialRigid; + + partial model PartialCompliant + "Compliant connection of two translational 1D flanges" + + Flange_a flange_a + "Left flange of compliant 1-dim. translational component" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + Flange_b flange_b + "Right flange of compliant 1-dim. translational component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + SI.Position s_rel(start=0) + "Relative distance (= flange_b.s - flange_a.s)"; + SI.Force f + "Force between flanges (positive in direction of flange axis R)"; + + equation + s_rel = flange_b.s - flange_a.s; + flange_b.f = f; + flange_a.f = -f; + annotation ( + Documentation(info=" +

+This is a 1D translational component with a compliant connection of two +translational 1D flanges where inertial effects between the two +flanges are not included. The absolute value of the force at the left and the right +flange is the same. It is used to built up springs, dampers etc. +

+ +"), Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Polygon( + points={{50,-90},{20,-80},{20,-100},{50,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), Line(points={{-60,-90},{20,-90}}, + color={0,0,0})})); + end PartialCompliant; + + partial model PartialCompliantWithRelativeStates + "Base model for the compliant connection of two translational 1-dim. shaft flanges where the relative position and relative velocities are used as states" + + parameter StateSelect stateSelect=StateSelect.prefer + "Priority to use phi_rel and w_rel as states" + annotation(HideResult=true, Dialog(tab="Advanced")); + parameter SI.Distance s_nominal=1e-4 + "Nominal value of s_rel (used for scaling)" annotation(Dialog(tab="Advanced")); + + SI.Position s_rel(start=0, stateSelect=stateSelect, nominal=s_nominal) + "Relative distance (= flange_b.s - flange_a.s)"; + SI.Velocity v_rel(start=0, stateSelect=stateSelect) + "Relative velocity (= der(s_rel))"; + + SI.Force f "Forces between flanges (= flange_b.f)"; + Translational.Interfaces.Flange_a flange_a + "Left flange of compliant 1-dim. translational component" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + Translational.Interfaces.Flange_b flange_b + "Right flange of compliant 1-dim. translational component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + + equation + s_rel = flange_b.s - flange_a.s; + v_rel = der(s_rel); + flange_b.f = f; + flange_a.f = -f; + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with a compliant connection of two +translational 1-dim. flanges where inertial effects between the two +flanges are neglected. The basic assumption is that the cut-forces +of the two flanges sum-up to zero, i.e., they have the same absolute value +but opposite sign: flange_a.f + flange_b.f = 0. This base class +is used to built up force elements such as springs, dampers, friction. +

+ +

+The difference to base class \"PartialCompliant\" is that the relative +distance and the relative velocity are defined as preferred states. +The reason is that for a large class of drive trains, +the absolute position is quickly increasing during operation. +Numerically, it is better to use relative distances between drive train components +because they remain in a limited size. For this reason, StateSelect.prefer +is set for the relative distance of this component. +

+ +

+In order to improve the numerics, a nominal value for the relative distance +should be set, since drive train distances are in a small order and +then step size control of the integrator is practically switched off for +such a variable. A default nominal value of s_nominal = 1e-4 is defined. +This nominal value might also be computed from other values, such +as \"s_nominal = f_nominal / c\" for a spring, if f_nominal +and c have more meaningful values for the user. +

+ +")); + end PartialCompliantWithRelativeStates; + + partial model PartialElementaryOneFlangeAndSupport + "Obsolete partial model. Use PartialElementaryOneFlangeAndSupport2." + extends Modelica.Icons.ObsoleteModel; + + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Modelica.SIunits.Length s + "Distance between flange and support (= flange.s - support.s)"; + Flange_b flange "Flange of component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + + protected + InternalSupport internalSupport(f=-flange.f) + "Internal support/housing of component as a model with connector flange (flange is either connected to support, if useSupport=true, or connected to fixed, if useSupport=false)" + annotation (Placement(transformation(extent={{-10,-90},{10,-70}}))); + Components.Fixed fixed if not useSupport + "Fixed support/housing, if not useSupport" + annotation (Placement(transformation(extent={{10,-97},{30,-77}}))); + public + Support support if useSupport "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + equation + s = flange.s - internalSupport.s; + connect(internalSupport.flange, support) annotation (Line( + points={{0,-80},{0,-100}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed.flange, internalSupport.flange) annotation (Line( + points={{20,-87},{20,-80},{0,-80}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with one flange and a support/housing. +It is used to build up elementary components of a drive train with +equations in the text layer. +

+ +

+If useSupport=true, the support connector is conditionally enabled +and needs to be connected.
+If useSupport=false, the support connector is conditionally disabled +and instead the component is internally fixed to ground. +

+ +"), Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={Text( + extent={{-38,-98},{-6,-96}}, + lineColor={95,95,95}, + textString="(if useSupport)"), Text( + extent={{24,-97},{64,-98}}, + lineColor={95,95,95}, + textString="(if not useSupport)")}), + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialElementaryOneFlangeAndSupport; + + partial model PartialElementaryOneFlangeAndSupport2 + "Partial model for a component with one translational 1-dim. shaft flange and a support used for textual modeling, i.e., for elementary models" + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Modelica.SIunits.Length s + "Distance between flange and support (= flange.s - support.s)"; + Flange_b flange "Flange of component" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + Support support(s=s_support, f=-flange.f) if useSupport + "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + protected + Modelica.SIunits.Length s_support "Absolute position of support flange"; + equation + s = flange.s - s_support; + if not useSupport then + s_support = 0; + end if; + annotation ( + Documentation(info=" +

+This is a 1-dim. translational component with one flange and a support/housing. +It is used to build up elementary components of a drive train with +equations in the text layer. +

+ +

+If useSupport=true, the support connector is conditionally enabled +and needs to be connected.
+If useSupport=false, the support connector is conditionally disabled +and instead the component is internally fixed to ground. +

+ +"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialElementaryOneFlangeAndSupport2; + + partial model PartialElementaryTwoFlangesAndSupport + "Obsolete partial model. Use PartialElementaryTwoFlangesAndSupport2." + extends Modelica.Icons.ObsoleteModel; + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Flange_a flange_a "Flange of left shaft" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, rotation=0))); + Flange_b flange_b "Flange of right shaft" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, rotation=0))); + Modelica.SIunits.Length s_a "Distance between left flange and support"; + Modelica.SIunits.Length s_b "Distance between right flange and support"; + protected + InternalSupport internalSupport(f=-flange_a.f - flange_b.f) + "Internal support/housing of component as a model with connector flange (flange is either connected to support, if useSupport=true, or connected to fixed, if useSupport=false)" + annotation (Placement(transformation(extent={{-10,-90},{10,-70}}))); + Components.Fixed fixed if not useSupport + "Fixed support/housing, if not useSupport" + annotation (Placement(transformation(extent={{10,-97},{30,-77}}))); + public + Support support if useSupport "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + equation + s_a = flange_a.s - internalSupport.s; + s_b = flange_b.s - internalSupport.s; + connect(internalSupport.flange, support) annotation (Line( + points={{0,-80},{0,-100}}, + color={0,127,0}, + smooth=Smooth.None)); + connect(fixed.flange, internalSupport.flange) annotation (Line( + points={{20,-87},{20,-80},{0,-80}}, + color={0,127,0}, + smooth=Smooth.None)); + annotation (Documentation(info=" +

+This is a 1-dim. translational component with two flanges and an additional support. +It is used e.g., to build up elementary ideal gear components. The component +contains the force balance, i.e., the sum of the forces of the connectors +is zero (therefore, components that are based on PartialGear cannot have +a mass). The support connector needs to be connected +to avoid the unphysical behavior that the +support force is required to be zero (= the default value, if the +connector is not connected). +

+ +"), Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100}, + {100,100}}), graphics={Text( + extent={{-38,-98},{-6,-96}}, + lineColor={95,95,95}, + textString="(if useSupport)"), Text( + extent={{24,-97},{64,-98}}, + lineColor={95,95,95}, + textString="(if not useSupport)")}), + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialElementaryTwoFlangesAndSupport; + + partial model PartialElementaryTwoFlangesAndSupport2 + "Partial model for a component with one translational 1-dim. shaft flange and a support used for textual modeling, i.e., for elementary models" + parameter Boolean useSupport=false + "= true, if support flange enabled, otherwise implicitly grounded" + annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); + Flange_a flange_a "Flange of left shaft" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, rotation=0))); + Flange_b flange_b "Flange of right shaft" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, rotation=0))); + Support support(s=s_support, f = -flange_a.f - flange_b.f) if useSupport + "Support/housing of component" + annotation (Placement(transformation(extent={{-10,-110},{10,-90}}))); + Modelica.SIunits.Length s_a "Distance between left flange and support"; + Modelica.SIunits.Length s_b "Distance between right flange and support"; + protected + Modelica.SIunits.Length s_support "Absolute position of support flange"; + equation + s_a = flange_a.s - s_support; + s_b = flange_b.s - s_support; + if not useSupport then + s_support = 0; + end if; + + annotation (Documentation(info=" +

+This is a 1-dim. translational component with two flanges and an additional support. +It is used e.g., to build up elementary ideal gear components. The component +contains the force balance, i.e., the sum of the forces of the connectors +is zero (therefore, components that are based on PartialGear cannot have +a mass). The support connector needs to be connected +to avoid the unphysical behavior that the +support force is required to be zero (= the default value, if the +connector is not connected). +

+ +"), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ + 100,100}}), graphics={ + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})})); + end PartialElementaryTwoFlangesAndSupport2; + + partial model PartialElementaryRotationalToTranslational + "Partial model to transform rotational into translational motion" + extends + Modelica.Mechanics.Rotational.Interfaces.PartialElementaryRotationalToTranslational; + annotation (Documentation(info=" +

This is a 1-dim. rotational component with

+
    +
  • one rotational flange,
  • +
  • one rotational support/housing,
  • +
  • one translational flange, and
  • +
  • one translational support/housing
  • +
+

This model is used to build up elementary components of a drive train transforming rotational into translational motion with equations in the text layer.

+

If useSupportR=true, the rotational support connector is conditionally enabled and needs to be connected.

+

If useSupportR=false, the rotational support connector is conditionally disabled and instead the rotational part is internally fixed to ground.

+

If useSupportT=true, the translational support connector is conditionally enabled and needs to be connected.

+

If useSupportT=false, the translational support connector is conditionally disabled and instead the translational part is internally fixed to ground.

+")); + end PartialElementaryRotationalToTranslational; + + partial model PartialForce + "Partial model of a force acting at the flange (accelerates the flange)" + extends PartialElementaryOneFlangeAndSupport2; + Modelica.SIunits.Force f "Accelerating force acting at flange (= flange.f)"; + equation + f = flange.f; + annotation ( + Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100, + 100}}), graphics={ + Rectangle( + extent={{-96,96},{96,-96}}, + lineColor={255,255,255}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Line(points={{0,-60},{0,-100}}, color={0,0,0}), + Text( + extent={{-150,140},{150,100}}, + lineColor={0,0,255}, + textString="%name"), + Line(points={{-78,80},{51,80}}, color={0,0,0}), + Polygon( + points={{81,80},{51,90},{51,70},{81,80}}, + lineColor={0,0,0}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-52,-60},{77,-60}}, color={0,0,0}), + Polygon( + points={{-82,-60},{-51,-50},{-51,-70},{-82,-60}}, + lineColor={0,0,0}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line( + visible=not useSupport, + points={{-50,-120},{-30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-120},{-10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-10,-120},{10,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{10,-120},{30,-100}}, + color={0,0,0}), + Line( + visible=not useSupport, + points={{-30,-100},{30,-100}}, + color={0,0,0})}), + Documentation(info=" +

+Partial model of force that accelerates the flange. +

+ +

+If useSupport=true, the support connector is conditionally enabled +and needs to be connected.
+If useSupport=false, the support connector is conditionally disabled +and instead the component is internally fixed to ground. +

+")); + end PartialForce; + + partial model PartialAbsoluteSensor + "Device to measure a single absolute flange variable" + + extends Modelica.Icons.TranslationalSensor; + + Interfaces.Flange_a flange + "Flange to be measured (flange axis directed in to cut plane, e. g. from left to right)" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + + equation + 0 = flange.f; + annotation ( + Documentation(info=" +

+This is the superclass of a 1D translational component with one flange and one +output signal in order to measure an absolute kinematic quantity in the flange +and to provide the measured signal as output signal for further processing +with the Modelica.Blocks blocks. +

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-100,-90},{-20,-90}}, color={0,0,0}), + Polygon( + points={{10,-90},{-20,-80},{-20,-100},{10,-90}}, + lineColor={128,128,128}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{100,0}}, color={0,0,127}), + Text( + extent={{-150,80},{150,40}}, + textString="%name", + lineColor={0,0,255})})); + end PartialAbsoluteSensor; + + partial model PartialRelativeSensor + "Device to measure a single relative variable between two flanges" + + extends Modelica.Icons.TranslationalSensor; + + Interfaces.Flange_a flange_a + "(left) driving flange (flange axis directed in to cut plane, e. g. from left to right)" + annotation (Placement(transformation(extent={{-110,-10},{-90,10}}, + rotation=0))); + Interfaces.Flange_b flange_b + "(right) driven flange (flange axis directed out of cut plane)" + annotation (Placement(transformation(extent={{90,-10},{110,10}}, + rotation=0))); + + equation + 0 = flange_a.f + flange_b.f; + annotation ( + Documentation(info=" +

+This is a superclass for 1D translational components with two rigidly connected +flanges and one output signal in order to measure relative kinematic quantities +between the two flanges or the cut-force in the flange and +to provide the measured signal as output signal for further processing +with the Modelica.Blocks blocks. +

+"), Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}), graphics={ + Line(points={{-51,34},{29,34}}, color={0,0,0}), + Polygon( + points={{59,34},{29,44},{29,24},{59,34}}, + lineColor={0,0,0}, + fillColor={128,128,128}, + fillPattern=FillPattern.Solid), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Text( + extent={{-150,100},{150,60}}, + textString="%name", + lineColor={0,0,255})})); + end PartialRelativeSensor; + + partial model PartialFriction "Base model of Coulomb friction elements" + + //extends Translational.Interfaces.PartialRigid; + parameter SI.Velocity v_small=1e-3 + "Relative velocity near to zero (see model info text)" + annotation(Dialog(tab="Advanced")); + // Equations to define the following variables have to be defined in subclasses + SI.Velocity v_relfric "Relative velocity between frictional surfaces"; + SI.Acceleration a_relfric + "Relative acceleration between frictional surfaces"; + //SI.Force f "Friction force (positive, if directed in opposite direction of v_rel)"; + SI.Force f0 "Friction force for v=0 and forward sliding"; + SI.Force f0_max "Maximum friction force for v=0 and locked"; + Boolean free "true, if frictional element is not active"; + // Equations to define the following variables are given in this class + Real sa(unit="1") + "Path parameter of friction characteristic f = f(a_relfric)"; + Boolean startForward(start=false, fixed=true) + "true, if v_rel=0 and start of forward sliding"; + Boolean startBackward(start=false, fixed=true) + "true, if v_rel=0 and start of backward sliding"; + Boolean locked(start=false) "true, if v_rel=0 and not sliding"; + constant Integer Unknown=3 "Value of mode is not known"; + constant Integer Free=2 "Element is not active"; + constant Integer Forward=1 "v_rel > 0 (forward sliding)"; + constant Integer Stuck=0 + "v_rel = 0 (forward sliding, locked or backward sliding)"; + constant Integer Backward=-1 "v_rel < 0 (backward sliding)"; + Integer mode( + final min=Backward, + final max=Unknown, + start=Unknown, fixed=true); + protected + constant SI.Acceleration unitAcceleration = 1 annotation(HideResult=true); + constant SI.Force unitForce = 1 annotation(HideResult=true); + equation + /* Friction characteristic + (locked is introduced to help the Modelica translator determining + the different structural configurations, + if for each configuration special code shall be generated) +*/ + startForward = pre(mode) == Stuck and (sa > f0_max/unitForce or pre(startForward) + and sa > f0/unitForce) or pre(mode) == Backward and v_relfric > v_small or + initial() and (v_relfric > 0); + startBackward = pre(mode) == Stuck and (sa < -f0_max/unitForce or pre( + startBackward) and sa < -f0/unitForce) or pre(mode) == Forward and v_relfric < + -v_small or initial() and (v_relfric < 0); + locked = not free and not (pre(mode) == Forward or startForward or pre( + mode) == Backward or startBackward); + + a_relfric/unitAcceleration = if locked then 0 else + if free then sa else + if startForward then sa - f0_max/unitForce else + if startBackward then sa + f0_max/unitForce else + if pre(mode) == Forward then sa - f0_max/unitForce else + sa + f0_max/unitForce; + + /* Friction torque has to be defined in a subclass. Example for a clutch: + f = if locked then sa else + if free then 0 else + cgeo*fn*(if startForward then Math.tempInterpol1( v_relfric, mue_pos, 2) else + if startBackward then -Math.tempInterpol1(-v_relfric, mue_pos, 2) else + if pre(mode) == Forward then Math.tempInterpol1( v_relfric, mue_pos, 2) else + -Math.tempInterpol1(-v_relfric, mue_pos, 2)); +*/ + // finite state machine to determine configuration + mode = if free then Free else + (if (pre(mode) == Forward or pre(mode) == Free or startForward) and v_relfric > 0 then + Forward else + if (pre(mode) == Backward or pre(mode) == Free or startBackward) and v_relfric < 0 then + Backward else + Stuck); + annotation (Documentation(info=" +

+Basic model for Coulomb friction that models the stuck phase in a reliable way. +

+")); + end PartialFriction; + + annotation (Documentation(info=" +

+This package contains connectors and partial models for 1-dim. +translational mechanical components. The components of this package can +only be used as basic building elements for models. +

+ +")); + end Interfaces; + + annotation ( + Icon(coordinateSystem(preserveAspectRatio = true, extent = {{-100,-100},{100,100}}), graphics = { + Line( + origin = {14,53}, + points = {{-84,-73},{66,-73}}), + Rectangle( + origin = {14,53}, + lineColor = {64,64,64}, + fillColor = {192,192,192}, + fillPattern = FillPattern.Sphere, + extent = {{-81,-65},{-8,-22}}),Line(visible = true, + origin = {14,53}, + points = {{-8,-43},{-1,-43},{6,-64},{17,-23},{29,-65},{40,-23},{50,-44},{61,-44}}), + Line( + origin = {14,53}, + points = {{-59,-73},{-84,-93}}), + Line( + origin = {14,53}, + points = {{-11,-73},{-36,-93}}), + Line( + origin = {14,53}, + points = {{-34,-73},{-59,-93}}), + Line( + origin = {14,53}, + points = {{14,-73},{-11,-93}}), + Line( + origin = {14,53}, + points = {{39,-73},{14,-93}}), + Line( + origin = {14,53}, + points = {{63,-73},{38,-93}})}), + Documentation(info=" +

+This package contains components to model 1-dimensional translational +mechanical systems. +

+

+The filled and non-filled green squares at the left and +right side of a component represent mechanical flanges. +Drawing a line between such squares means that the corresponding +flanges are rigidly attached to each other. The components of this +library can be usually connected together in an arbitrary way. E.g. it is +possible to connect two springs or two sliding masses with inertia directly +together. +

The only connection restriction is that the Coulomb friction +elements (e.g., MassWithStopAndFriction) should be only connected +together provided a compliant element, such as a spring, is in between. +The reason is that otherwise the frictional force is not uniquely +defined if the elements are stuck at the same time instant (i.e., there +does not exist a unique solution) and some simulation systems may not be +able to handle this situation, since this leads to a singularity during +simulation. It can only be resolved in a \"clean way\" by combining the +two connected friction elements into +one component and resolving the ambiguity of the frictional force in the +stuck mode. +

+

Another restriction arises if the hard stops in model MassWithStopAndFriction are used, i. e. +the movement of the mass is limited by a stop at smax or smin. + This requires the states Stop.s and Stop.v . If these states are eliminated during the index reduction +the model will not work. To avoid this any inertias should be connected via springs +to the Stop element, other sliding masses, dampers or hydraulic chambers must be avoided.

+

+In the icon of every component an arrow is displayed in grey +color. This arrow characterizes the coordinate system in which the vectors +of the component are resolved. It is directed into the positive +translational direction (in the mathematical sense). +In the flanges of a component, a coordinate system is rigidly attached +to the flange. It is called flange frame and is directed in parallel +to the component coordinate system. As a result, e.g., the positive +cut-force of a \"left\" flange (flange_a) is directed into the flange, whereas +the positive cut-force of a \"right\" flange (flange_b) is directed out of the +flange. A flange is described by a Modelica connector containing +the following variables: +

+
+   Modelica.SIunits.Position s    \"Absolute position of flange\";
+   flow Modelica.SIunits.Force f  \"Cut-force in the flange\";
+
+ +

+This library is designed in a fully object oriented way in order that +components can be connected together in every meaningful combination +(e.g., direct connection of two springs or two shafts with inertia). +As a consequence, most models lead to a system of +differential-algebraic equations of index 3 (= constraint +equations have to be differentiated twice in order to arrive at +a state space representation) and the Modelica translator or +the simulator has to cope with this system representation. +According to our present knowledge, this requires that the +Modelica translator is able to symbolically differentiate equations +(otherwise it is e.g., not possible to provide consistent initial +conditions; even if consistent initial conditions are present, most +numerical DAE integrators can cope at most with index 2 DAEs). +

+ +

+In version 3.2 of the Modelica Standard Library, all dissipative components +of the Translational library got an optional heatPort connector to which the +dissipated energy is transported in form of heat. This connector is enabled +via parameter \"useHeatPort\". If the heatPort connector is enabled, +it must be connected, and if it is not enabled, it must not be connected. +Independently, whether the heatPort is enabled or not, +the dissipated power is available from the new variable \"lossPower\" (which is +positive if heat is flowing out of the heatPort). For an example, see +Examples.HeatLosses. +

+ +
+
Library Officer +
Martin Otter
+ Deutsches Zentrum für Luft und Raumfahrt e.V. (DLR)
+ Institut für Robotik und Mechatronik (DLR-RM)
+ Abteilung Systemdynamik und Regelungstechnik
+ Postfach 1116
+ D-82230 Wessling
+ Germany
+ email: Martin.Otter@dlr.de

+
+ +

+Contributors to this library: +

+ +
    +
  • Main author until 2006:
    + Peter Beater
    + Universität Paderborn, Abteilung Soest
    + Fachbereich Maschinenbau/Automatisierungstechnik
    + Lübecker Ring 2
    + D 59494 Soest
    + Germany
    + email: info@beater.de

    +
  • + +
  • Anton Haumer
    + Technical Consulting & Electrical Engineering
    + A-3423 St.Andrae-Woerdern, Austria
    + email: a.haumer@haumer.at

  • + +
  • Martin Otter (DLR-RM)
  • +
+ +

+Copyright © 1998-2013, Modelica Association, Anton Haumer and Universität Paderborn, FB 12. +

+

+This Modelica package is free software and the use is completely at your own risk; it can be redistributed and/or modified under the terms of the Modelica License 2. For license conditions (including the disclaimer of warranty) see Modelica.UsersGuide.ModelicaLicense2 or visit https://www.modelica.org/licenses/ModelicaLicense2. +

+", revisions=" +
    +
  • Version 1.2.0 2010-07-22 + by Anton Haumer and Martin Otter
    + heatPort introduced for all dissipative elements, and + text in icons improved. +
  • + +
  • Version 1.1.0 2007-11-16 + by Anton Haumer
    + Redesign for Modelica 3.0-compliance
    + Added new components according to Mechanics.Rotational library +
  • + +
  • Version 1.01 (July 18, 2001) + by Peter Beater
    + Assert statement added to \"Stop\", small bug fixes in examples. +
  • + +
  • Version 1.0 (January 5, 2000) + by Peter Beater
    + Realized a first version based on Modelica library Mechanics.Rotational + by Martin Otter and an existing Dymola library onedof.lib by Peter Beater.
  • +
+")); +end Translational; diff --git a/samples/Modelica/modelica.mo b/samples/Modelica/modelica.mo new file mode 100644 index 00000000..5462de87 --- /dev/null +++ b/samples/Modelica/modelica.mo @@ -0,0 +1,285 @@ +within Modelica.Electrical.Analog; +package Sensors "Potential, voltage, current, and power sensors" + + extends Modelica.Icons.SensorsPackage; + + model PotentialSensor "Sensor to measure the potential" + extends Modelica.Icons.RotationalSensor; + + Interfaces.PositivePin p "pin to be measured" annotation (Placement( + transformation(extent={{-110,-10},{-90,10}}, rotation=0))); + Modelica.Blocks.Interfaces.RealOutput phi + "Absolute voltage potential as output signal" + annotation (Placement(transformation(extent={{100,-10},{120,10}}, + rotation=0))); + equation + p.i = 0; + phi = p.v; + annotation ( + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={ + Text( + extent={{-29,-11},{30,-70}}, + lineColor={0,0,0}, + textString="V"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{100,0},{70,0}}, color={0,0,255}), + Text( + extent={{-150,80},{150,120}}, + textString="%name", + lineColor={0,0,255})}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={Line(points={{-70,0},{-96,0}}, color={0,0,0}), + Line(points={{100,0},{70,0}}, color={0,0,255})}), + Documentation(revisions=" +
    +
  • 1998 + by Christoph Clauss
    initially implemented
    +
  • +
+", info=" +

The potential sensor converts the voltage of a node (with respect to the ground node) into a real valued signal. It does not influence the current sum at the node which voltage is measured, therefore, the electrical behavior is not influenced by the sensor.

+")); + end PotentialSensor; + + model VoltageSensor "Sensor to measure the voltage between two pins" + extends Modelica.Icons.RotationalSensor; + + Interfaces.PositivePin p "positive pin" annotation (Placement( + transformation(extent={{-110,-10},{-90,10}}, rotation=0))); + Interfaces.NegativePin n "negative pin" annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + Modelica.Blocks.Interfaces.RealOutput v + "Voltage between pin p and n (= p.v - n.v) as output signal" + annotation (Placement(transformation( + origin={0,-100}, + extent={{10,-10},{-10,10}}, + rotation=90))); + + equation + p.i = 0; + n.i = 0; + v = p.v - n.v; + annotation ( + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={ + Text( + extent={{-29,-11},{30,-70}}, + lineColor={0,0,0}, + textString="V"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Line(points={{0,-90},{0,-70}}, color={0,0,255}), + Text( + extent={{-150,80},{150,120}}, + textString="%name", + lineColor={0,0,255})}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={ + Line(points={{-70,0},{-96,0}}, color={0,0,0}), + Line(points={{70,0},{96,0}}, color={0,0,0}), + Line(points={{0,-90},{0,-70}}, color={0,0,255})}), + Documentation(revisions=" +
    +
  • 1998 + by Christoph Clauss
    initially implemented
    +
  • +
+", info=" +

The voltage sensor converts the voltage between the two connectors into a real valued signal. It does not influence the current sum at the nodes in between the voltage is measured, therefore, the electrical behavior is not influenced by the sensor.

+")); + end VoltageSensor; + + model CurrentSensor "Sensor to measure the current in a branch" + extends Modelica.Icons.RotationalSensor; + + Interfaces.PositivePin p "positive pin" annotation (Placement( + transformation(extent={{-110,-10},{-90,10}}, rotation=0))); + Interfaces.NegativePin n "negative pin" annotation (Placement( + transformation(extent={{90,-10},{110,10}}, rotation=0))); + Modelica.Blocks.Interfaces.RealOutput i + "current in the branch from p to n as output signal" + annotation (Placement(transformation( + origin={0,-100}, + extent={{10,-10},{-10,10}}, + rotation=90))); + + equation + p.v = n.v; + p.i = i; + n.i = -i; + annotation ( + Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={ + Text( + extent={{-29,-11},{30,-70}}, + lineColor={0,0,0}, + textString="A"), + Line(points={{-70,0},{-90,0}}, color={0,0,0}), + Text( + extent={{-150,80},{150,120}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{70,0},{90,0}}, color={0,0,0}), + Line(points={{0,-90},{0,-70}}, color={0,0,255})}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={1,1}), graphics={ + Text( + extent={{-153,79},{147,119}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{-70,0},{-96,0}}, color={0,0,0}), + Line(points={{70,0},{96,0}}, color={0,0,0}), + Line(points={{0,-90},{0,-70}}, color={0,0,255})}), + Documentation(revisions=" +
    +
  • 1998 + by Christoph Clauss
    initially implemented
    +
  • +
+", info=" +

The current sensor converts the current flowing between the two connectors into a real valued signal. The two connectors are in the sensor connected like a short cut. The sensor has to be placed within an electrical connection in series. It does not influence the current sum at the connected nodes. Therefore, the electrical behavior is not influenced by the sensor.

+")); + end CurrentSensor; + +model PowerSensor "Sensor to measure the power" + + Modelica.Electrical.Analog.Interfaces.PositivePin pc + "Positive pin, current path" + annotation (Placement(transformation(extent={{-90,-10},{-110,10}}, rotation= + 0))); + Modelica.Electrical.Analog.Interfaces.NegativePin nc + "Negative pin, current path" + annotation (Placement(transformation(extent={{110,-10},{90,10}}, rotation=0))); + Modelica.Electrical.Analog.Interfaces.PositivePin pv + "Positive pin, voltage path" + annotation (Placement(transformation(extent={{-10,110},{10,90}}, rotation=0))); + Modelica.Electrical.Analog.Interfaces.NegativePin nv + "Negative pin, voltage path" + annotation (Placement(transformation(extent={{10,-110},{-10,-90}}, rotation= + 0))); + Modelica.Blocks.Interfaces.RealOutput power + annotation (Placement(transformation( + origin={-80,-110}, + extent={{-10,10},{10,-10}}, + rotation=270))); + Modelica.Electrical.Analog.Sensors.VoltageSensor voltageSensor + annotation (Placement(transformation( + origin={0,-30}, + extent={{10,-10},{-10,10}}, + rotation=90))); + Modelica.Electrical.Analog.Sensors.CurrentSensor currentSensor + annotation (Placement(transformation(extent={{-50,-10},{-30,10}}, rotation= + 0))); + Modelica.Blocks.Math.Product product + annotation (Placement(transformation( + origin={-30,-50}, + extent={{-10,-10},{10,10}}, + rotation=270))); + +equation + connect(pv, voltageSensor.p) annotation (Line(points={{0,100},{0,-20},{ + 6.12323e-016,-20}}, color={0,0,255})); + connect(voltageSensor.n, nv) annotation (Line(points={{-6.12323e-016,-40},{ + -6.12323e-016,-63},{0,-63},{0,-100}}, color={0,0,255})); + connect(pc, currentSensor.p) + annotation (Line(points={{-100,0},{-50,0}}, color={0,0,255})); + connect(currentSensor.n, nc) + annotation (Line(points={{-30,0},{100,0}}, color={0,0,255})); + connect(currentSensor.i, product.u2) annotation (Line(points={{-40,-10},{-40, + -30},{-36,-30},{-36,-38}}, color={0,0,127})); + connect(voltageSensor.v, product.u1) annotation (Line(points={{10,-30},{-24, + -30},{-24,-38}}, color={0,0,127})); + connect(product.y, power) annotation (Line(points={{-30,-61},{-30,-80},{-80, + -80},{-80,-110}}, color={0,0,127})); + annotation (Icon(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={2,2}), graphics={ + Ellipse( + extent={{-70,70},{70,-70}}, + lineColor={0,0,0}, + fillColor={255,255,255}, + fillPattern=FillPattern.Solid), + Line(points={{0,100},{0,70}}, color={0,0,255}), + Line(points={{0,-70},{0,-100}}, color={0,0,255}), + Line(points={{-80,-100},{-80,0}}, color={0,0,255}), + Line(points={{-100,0},{100,0}}, color={0,0,255}), + Text( + extent={{150,120},{-150,160}}, + textString="%name", + lineColor={0,0,255}), + Line(points={{0,70},{0,40}}, color={0,0,0}), + Line(points={{22.9,32.8},{40.2,57.3}}, color={0,0,0}), + Line(points={{-22.9,32.8},{-40.2,57.3}}, color={0,0,0}), + Line(points={{37.6,13.7},{65.8,23.9}}, color={0,0,0}), + Line(points={{-37.6,13.7},{-65.8,23.9}}, color={0,0,0}), + Line(points={{0,0},{9.02,28.6}}, color={0,0,0}), + Polygon( + points={{-0.48,31.6},{18,26},{18,57.2},{-0.48,31.6}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Ellipse( + extent={{-5,5},{5,-5}}, + lineColor={0,0,0}, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid), + Text( + extent={{-29,-11},{30,-70}}, + lineColor={0,0,0}, + textString="P")}), + Diagram(coordinateSystem( + preserveAspectRatio=true, + extent={{-100,-100},{100,100}}, + grid={2,2}), graphics), + Documentation(info=" +

This power sensor measures instantaneous electrical power of a singlephase system and has a separated voltage and current path. The pins of the voltage path are pv and nv, the pins of the current path are pc and nc. The internal resistance of the current path is zero, the internal resistance of the voltage path is infinite.

+", revisions=" +
    +
  • January 12, 2006 by Anton Haumer implemented
  • +
+")); +end PowerSensor; + annotation ( + Documentation(info=" +

This package contains potential, voltage, and current sensors. The sensors can be used to convert voltages or currents into real signal values o be connected to components of the Blocks package. The sensors are designed in such a way that they do not influence the electrical behavior.

+", + revisions=" +
+
+Main Authors: +
+Christoph Clauß + <Christoph.Clauss@eas.iis.fraunhofer.de>
+ André Schneider + <Andre.Schneider@eas.iis.fraunhofer.de>
+ Fraunhofer Institute for Integrated Circuits
+ Design Automation Department
+ Zeunerstraße 38
+ D-01069 Dresden
+

+

+Copyright: +
+Copyright © 1998-2010, Modelica Association and Fraunhofer-Gesellschaft.
+The Modelica package is free software; it can be redistributed and/or modified +under the terms of the Modelica license, see the license conditions +and the accompanying disclaimer in the documentation of package +Modelica in file \"Modelica/package.mo\".
+

+

+")); +end Sensors; diff --git a/samples/NewLisp/irc.lsp b/samples/NewLisp/irc.lsp new file mode 100644 index 00000000..0cac4034 --- /dev/null +++ b/samples/NewLisp/irc.lsp @@ -0,0 +1,239 @@ +#!/usr/bin/env newlisp + +;; @module IRC +;; @description a basic irc library +;; @version early alpha! 0.1 2013-01-02 20:11:22 +;; @author cormullion +;; Usage: +;; (IRC:init "newlithper") ; a username/nick (not that one obviously :-) +;; (IRC:connect "irc.freenode.net" 6667) ; irc/server +;; (IRC:join-channel {#newlisp}) ; join a room +;; either (IRC:read-irc-loop) ; loop - monitor only, no input +;; or (IRC:session) ; a command-line session, end with /QUIT + +(context 'IRC) + (define Inickname) + (define Ichannels) + (define Iserver) + (define Iconnected) + (define Icallbacks '()) + (define Idle-time 400) ; seconds + (define Itime-stamp) ; time since last message was processed + +(define (register-callback callback-name callback-function) + (println {registering callback for } callback-name { : } (sym (term callback-function) (prefix callback-function))) + (push (list callback-name (sym (term callback-function) (prefix callback-function))) Icallbacks)) + +(define (deregister-callback callback-name) + (println {deregistering callback for } callback-name) + (setf (assoc "idle-event" Icallbacks) nil) + (println {current callbacks: } Icallbacks)) + +(define (do-callback callback-name data) + (when (set 'func (lookup callback-name Icallbacks)) ; find first callback + (if-not (catch (apply func (list data)) 'error) + (println {error in callback } callback-name {: } error)))) + +(define (do-callbacks callback-name data) + (dolist (rf (ref-all callback-name Icallbacks)) + (set 'callback-entry (Icallbacks (first rf))) + (when (set 'func (last callback-entry)) + (if-not (catch (apply func (list data)) 'error) + (println {error in callback } callback-name {: } error))))) + +(define (init str) + (set 'Inickname str) + (set 'Iconnected nil) + (set 'Ichannels '()) + (set 'Itime-stamp (time-of-day))) + +(define (connect server port) + (set 'Iserver (net-connect server port)) + (net-send Iserver (format "USER %s %s %s :%s\r\n" Inickname Inickname Inickname Inickname)) + (net-send Iserver (format "NICK %s \r\n" Inickname)) + (set 'Iconnected true) + (do-callbacks "connect" (list (list "server" server) (list "port" port)))) + +(define (identify password) + (net-send Iserver (format "PRIVMSG nickserv :identify %s\r\n" password))) + +(define (join-channel channel) + (when (net-send Iserver (format "JOIN %s \r\n" channel)) + (push channel Ichannels) + (do-callbacks "join-channel" (list (list "channel" channel) (list "nickname" Inickname))))) + +(define (part chan) + (if-not (empty? chan) + ; leave specified + (begin + (net-send Iserver (format "PART %s\r\n" chan)) + (replace channel Ichannels) + (do-callbacks "part" (list (list "channel" channel)))) + ; leave all + (begin + (dolist (channel Ichannels) + (net-send Iserver (format "PART %s\r\n" channel)) + (replace channel Ichannels) + (do-callbacks "part" (list (list "channel" channel))))))) + +(define (do-quit message) + (do-callbacks "quit" '()) ; chance to do stuff before quit... + (net-send Iserver (format "QUIT :%s\r\n" message)) + (sleep 1000) + (set 'Ichannels '()) + (close Iserver) + (set 'Iconnected nil)) + +(define (privmsg user message) + (net-send Iserver (format "PRIVMSG %s :%s\r\n" user message))) + +(define (notice user message) + (net-send Iserver (format "NOTICE %s :%s\r\n" user message))) + +(define (send-to-server message (channel nil)) + (cond + ((starts-with message {/}) ; default command character + (set 'the-message (replace "^/" (copy message) {} 0)) ; keep original + (net-send Iserver (format "%s \r\n" the-message)) ; send it + ; do a quit + (if (starts-with (lower-case the-message) "quit") + (do-quit { enough}))) + (true + (if (nil? channel) + ; say to all channels + (dolist (c Ichannels) + (net-send Iserver (format "PRIVMSG %s :%s\r\n" c message))) + ; say to specified channel + (if (find channel Ichannels) + (net-send Iserver (format "PRIVMSG %s :%s\r\n" channel message)))))) + (do-callbacks "send-to-server" (list (list "channel" channel) (list "message" message)))) + +(define (process-command sender command text) + (cond + ((= sender "PING") + (net-send Iserver (format "PONG %s\r\n" command))) + ((or (= command "NOTICE") (= command "PRIVMSG")) + (process-message sender command text)) + ((= command "JOIN") + (set 'username (first (clean empty? (parse sender {!|:} 0)))) + (set 'channel (last (clean empty? (parse sender {!|:} 0)))) + (println {username } username { joined } channel) + (do-callbacks "join" (list (list "channel" channel) (list "username" username)))) + (true + nil))) + +(define (process-message sender command text) + (let ((username {} target {} message {})) + (set 'username (first (clean empty? (parse sender {!|:} 0)))) + (set 'target (trim (first (clean empty? (parse text {!|:} 0))))) + (set 'message (slice text (+ (find {:} text) 1))) + (cond + ((starts-with message "\001") + (process-ctcp username target message)) + ((find target Ichannels) + (cond + ((= command {PRIVMSG}) + (do-callbacks "channel-message" (list (list "channel" target) (list "username" username) (list "message" message)))) + ((= command {NOTICE}) + (do-callbacks "channel-notice" (list (list "channel" target) (list "username" username) (list "message" message)))))) + ((= target Inickname) + (cond + ((= command {PRIVMSG}) + (do-callbacks "private-message" (list (list "username" username) (list "message" message)))) + ((= command {NOTICE}) + (do-callbacks "private-notice" (list (list "username" username) (list "message" message)))))) + (true + nil)))) + +(define (process-ctcp username target message) + (cond + ((starts-with message "\001VERSION\001") + (net-send Iserver (format "NOTICE %s :\001VERSION %s\001\r\n" username message))) + ((starts-with message "\001PING") + (set 'data (first (rest (clean empty? (parse message { } 0))))) + (set 'data (trim data "\001" "\001")) + (net-send Iserver (format "NOTICE %s :\001PING %s\001\r\n" username data))) + ((starts-with message "\001ACTION") +; (set 'data (first (rest (clean empty? (parse message { } 0))))) +; (set 'data (join data { })) +; (set 'data (trim data "\001" "\001")) + (if (find target Ichannels) + (do-callbacks "channel-action" (list (list "username" username) (list "message" message)))) + (if (= target Inickname) + (do-callbacks "private-action" (list (list "username" username) (list "message" message))))) + ((starts-with message "\001TIME\001") + (net-send Iserver (format "NOTICE %s:\001TIME :%s\001\r\n" username (date)))))) + +(define (parse-buffer raw-buffer) + (let ((messages (clean empty? (parse raw-buffer "\r\n" 0))) + (sender {} command {} text {})) + ; check for elapsed time since last activity + (when (> (sub (time-of-day) Itime-stamp) (mul Idle-time 1000)) + (do-callbacks "idle-event") + (set 'Itime-stamp (time-of-day))) + (dolist (message messages) + (set 'message-parts (parse message { })) + (unless (empty? message-parts) + (set 'sender (first message-parts)) + (catch (set 'command (first (rest message-parts))) 'error) + (catch (set 'text (join (rest (rest message-parts)) { })) 'error)) + (process-command sender command text)))) + +(define (read-irc) + (let ((buffer {})) + (when (!= (net-peek Iserver) 0) + (net-receive Iserver buffer 8192 "\n") + (unless (empty? buffer) + (parse-buffer buffer))))) + +(define (read-irc-loop) ; monitoring + (let ((buffer {})) + (while Iconnected + (read-irc) + (sleep 1000)))) + +(define (print-raw-message data) ; example of using a callback + (set 'raw-data (lookup "message" data)) + (set 'channel (lookup "channel" data)) + (set 'message-text raw-data) + (println (date (date-value) 0 {%H:%M:%S }) username {> } message-text)) + +(define (print-outgoing-message data) + (set 'raw-data (lookup "message" data)) + (set 'channel (lookup "channel" data)) + (set 'message-text raw-data) + (println (date (date-value) 0 {%H:%M:%S }) Inickname {> } message-text)) + +(define (session); interactive terminal + ; must add callbacks to display messages + (register-callback "channel-message" 'print-raw-message) + (register-callback "send-to-server" 'print-outgoing-message) + (while Iconnected + (while (zero? (peek 0)) + (read-irc) + (sleep 1000)) + (send-to-server (string (read-line 0)))) + (println {finished session } (date)) + (exit)) + +; end of IRC code + +[text] + +simple bot code: +(load (string (env {HOME}) {/projects/programming/newlisp-projects/irc.lsp})) +(context 'BOT) +(define bot-name "bot") +(define (join-channel data) + (println {in BOT:join-channel with data: } data)) +(define (process-message data) + ????) +(IRC:register-callback "join-channel" 'join-channel) +(IRC:register-callback "channel-message" 'process-message) +(IRC:register-callback "idle-event" 'do-idle-event) +(IRC:register-callback "send-to-server" 'do-send-event) +(IRC:init bot-name) +(IRC:connect "irc.freenode.net" 6667) +(IRC:join-channel {#newlisp}) +(IRC:read-irc-loop) +[/text] \ No newline at end of file diff --git a/samples/NewLisp/log-to-database.lisp b/samples/NewLisp/log-to-database.lisp new file mode 100644 index 00000000..60af8406 --- /dev/null +++ b/samples/NewLisp/log-to-database.lisp @@ -0,0 +1,195 @@ +(module "sqlite3.lsp") ; loads the SQLite3 database module + +; FUNCTIONS------------------------------------------------- + +(define (displayln str-to-display) + (println str-to-display) +) + +(define (open-database sql-db-to-open) + (if (sql3:open (string sql-db-to-open ".db")) + (displayln "") + (displayln "There was a problem opening the database " sql-db-to-open ": " (sql3:error)))) + +(define (close-database) + (if (sql3:close) + (displayln "") + (displayln "There was a problem closing the database: " (sql3:error)))) + +;====== SAFE-FOR-SQL =============================================================== +; this function makes strings safe for inserting into SQL statements +; to avoid SQL injection issues +; it's simple right now but will add to it later +;=================================================================================== +(define (safe-for-sql str-sql-query) + (if (string? str-sql-query) (begin + (replace "&" str-sql-query "&") + (replace "'" str-sql-query "'") + (replace "\"" str-sql-query """) + )) + (set 'result str-sql-query)) + +(define (query sql-text) + (set 'sqlarray (sql3:sql sql-text)) ; results of query + (if sqlarray + (setq query-return sqlarray) + (if (sql3:error) + (displayln (sql3:error) " query problem ") + (setq query-return nil)))) + +(define-macro (create-record) + ; first save the values + (set 'temp-record-values nil) + (set 'temp-table-name (first (args))) + ;(displayln "
Arguments: " (args)) + (dolist (s (rest (args))) (push (eval s) temp-record-values -1)) + ; now save the arguments as symbols under the context "DB" + (dolist (s (rest (args))) + (set 'temp-index-num (string $idx)) ; we need to number the symbols to keep them in the correct order + (if (= (length temp-index-num) 1) (set 'temp-index-num (string "0" temp-index-num))) ; leading 0 keeps the max at 100. + (sym (string temp-index-num s) 'DB)) + ; now create the sql query + (set 'temp-sql-query (string "INSERT INTO " temp-table-name " (")) + ;(displayln "

TABLE NAME: " temp-table-name) + ;(displayln "

SYMBOLS: " (symbols DB)) + ;(displayln "
VALUES: " temp-record-values) + (dolist (d (symbols DB)) (extend temp-sql-query (rest (rest (rest (rest (rest (string d)))))) ", ")) + (set 'temp-sql-query (chop (chop temp-sql-query))) + (extend temp-sql-query ") VALUES (") + (dolist (q temp-record-values) + (if (string? q) (extend temp-sql-query "'")) ; only quote if value is non-numeric + (extend temp-sql-query (string (safe-for-sql q))) + (if (string? q) (extend temp-sql-query "'")) ; close quote if value is non-numeric + (extend temp-sql-query ", ")) ; all values are sanitized to avoid SQL injection + (set 'temp-sql-query (chop (chop temp-sql-query))) + (extend temp-sql-query ");") + ;(displayln "

***** SQL QUERY: " temp-sql-query) + (displayln (query temp-sql-query)) ; actually run the query against the database + (delete 'DB) ; we're done, so delete all symbols in the DB context. +) + +(define-macro (update-record) + ; first save the values + (set 'temp-record-values nil) + (set 'temp-table-name (first (args))) + (set 'continue true) ; debugging + (dolist (s (rest (args))) (push (eval s) temp-record-values -1)) + ; now save the arguments as symbols under the context "D2" + (dolist (st (rest (args))) + (set 'temp-index-num (string $idx)) ; we need to number the symbols to keep them in the correct order + (if (= (length temp-index-num) 1) (set 'temp-index-num (string "0" temp-index-num))) ; leading 0 keeps the max at 100. + ;(displayln "
SYMBOL>>>>" (string temp-index-num st) "<<<") ; debugging + (sym (string temp-index-num st) 'D2) + ) + (if continue (begin ; --- temporary debugging + ; now create the sql query + (set 'temp-sql-query (string "UPDATE " temp-table-name " SET ")) + ;(displayln "

TABLE NAME: " temp-table-name) + ;(displayln "

SYMBOLS: " (symbols D2)) + ;(displayln "
VALUES: " temp-record-values) + (dolist (d (rest (symbols D2))) ; ignore the first argument, as it will be the ConditionColumn for later + (extend temp-sql-query (rest (rest (rest (rest (rest (string d)))))) "=") + (set 'q (temp-record-values (+ $idx 1))) + (if (string? q) (extend temp-sql-query "'")) ; only quote if value is non-numeric + (extend temp-sql-query (string (safe-for-sql q))) + (if (string? q) (extend temp-sql-query "'")) ; close quote if value is non-numeric + (extend temp-sql-query ", ") ; all values are sanitized to avoid SQL injection + ) + (set 'temp-sql-query (chop (chop temp-sql-query))) + ; okay now add the ConditionColumn value + (extend temp-sql-query (string " WHERE " (rest (rest (rest (rest (rest (string (first (symbols D2)))))))) "=")) + (if (string? (first temp-record-values)) (extend temp-sql-query "'")) + (extend temp-sql-query (string (safe-for-sql (first temp-record-values)))) + (if (string? (first temp-record-values)) (extend temp-sql-query "'")) + (extend temp-sql-query ";") + ;(displayln "

***** SQL QUERY: " temp-sql-query) + (query temp-sql-query) ; actually run the query against the database + (delete 'D2) ; we're done, so delete all symbols in the DB context. + )) ; --- end temporary debugging +) + +(define-macro (delete-record) + (set 'temp-table-name (first (args))) + (set 'temp-record-values nil) + (dolist (s (rest (args))) (push (eval s) temp-record-values -1)) ; only one value for NOW... + (sym (first (rest (args))) 'DB) ; put the second argument (for now) into a symbol in the DB context + ; this will have to be in a dolist loop of (rest (args)) when I add more + (set 'temp-sql-query (string "DELETE FROM " temp-table-name " WHERE ")) + (dolist (d (symbols DB)) (extend temp-sql-query (rest (rest (rest (string d)))))) + (extend temp-sql-query "=") + ; why am I doing a loop here? There should be only one value, right? But maybe for future extension... + (dolist (q temp-record-values) + (if (string? q) (extend temp-sql-query "'")) ; only quote if value is non-numeric + (extend temp-sql-query (string (safe-for-sql q))) + (if (string? q) (extend temp-sql-query "'"))) ; close quote if value is non-numeric + (extend temp-sql-query ";") + ;(displayln "TEMP-DELETE-QUERY: " temp-sql-query) + (query temp-sql-query) + (delete 'DB) ; we're done, so delete all symbols in the DB context. +) + +(define-macro (get-record) + (set 'temp-table-name (first (args))) + ; if you have more arguments than just the table name, they become the elements of the WHERE clause + (if (> (length (args)) 1) (begin + (set 'temp-record-values nil) + (dolist (s (rest (args))) (push (eval s) temp-record-values -1)) ; only one value for NOW... + (sym (first (rest (args))) 'DB) ; put the second argument (for now) into a symbol in the DB context + ; this will have to be in a dolist loop of (rest (args)) when I add more + (set 'temp-sql-query (string "SELECT * FROM " temp-table-name " WHERE ")) + (dolist (d (symbols DB)) (extend temp-sql-query (rest (rest (rest (string d)))))) + (extend temp-sql-query "=") + ; why am I doing a loop here? There should be only one value, right? But maybe for future extension... + (dolist (q temp-record-values) + (if (string? q) (extend temp-sql-query "'")) ; only quote if value is non-numeric + (extend temp-sql-query (string (safe-for-sql q))) + (if (string? q) (extend temp-sql-query "'"))) ; close quote if value is non-numeric + (extend temp-sql-query ";") + ) + ; otherwise, just get everything in that table + (set 'temp-sql-query (string "SELECT * FROM " temp-table-name ";")) + ) + ;(displayln "TEMP-GET-QUERY: " temp-sql-query) + (delete 'DB) ; we're done, so delete all symbols in the DB context. + (set 'return-value (query temp-sql-query)) ; this returns a list of everything in the record +) + +; END FUNCTIONS =================== + + +(open-database "SERVER-LOGS") +(query "CREATE TABLE Logs (Id INTEGER PRIMARY KEY, IP TEXT, UserId TEXT, UserName TEXT, Date DATE, Request TEXT, Result TEXT, Size INTEGER, Referrer TEXT, UserAgent TEXT)") +;(print (query "SELECT * from SQLITE_MASTER;")) +(set 'access-log (read-file "/var/log/apache2/access.log")) +(set 'access-list (parse access-log "\n")) +(set 'max-items (integer (first (first (query "select count(*) from Logs"))))) +(println "Number of items in database: " max-items) +(println "Number of lines in log: " (length access-list)) +(dolist (line access-list) + (set 'line-list (parse line)) + ;(println "Line# " $idx " - " line-list) + ;(println "Length of line: " (length line-list)) + (if (> (length line-list) 0) (begin + (++ max-items) + (set 'Id max-items) (print $idx "/" (length access-list)) + (set 'IP (string (line-list 0) (line-list 1) (line-list 2))) + (set 'UserId (line-list 3)) + (set 'UserName (line-list 4)) + (set 'Date (line-list 5)) + (set 'Date (trim Date "[")) + (set 'Date (trim Date "]")) + ;(println "DATE: " Date) + (set 'date-parsed (date-parse Date "%d/%b/%Y:%H:%M:%S -0700")) + ;(println "DATE-PARSED: " date-parsed) + (set 'Date (date date-parsed 0 "%Y-%m-%dT%H:%M:%S")) + (println " " Date) + (set 'Request (line-list 6)) + (set 'Result (line-list 7)) + (set 'Size (line-list 8)) + (set 'Referrer (line-list 9)) + (set 'UserAgent (line-list 10)) + (create-record "Logs" Id IP UserId UserName Date Request Result Size Referrer UserAgent) + )) +) +(close-database) +(exit) \ No newline at end of file diff --git a/samples/Nit/file.nit b/samples/Nit/file.nit new file mode 100644 index 00000000..889526fc --- /dev/null +++ b/samples/Nit/file.nit @@ -0,0 +1,798 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2004-2008 Jean Privat +# Copyright 2008 Floréal Morandat +# Copyright 2008 Jean-Sébastien Gélinas +# +# This file is free software, which comes along with NIT. This software is +# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. You can modify it is you want, provided this header +# is kept unaltered, and a notification of the changes is added. +# You are allowed to redistribute it and sell it, alone or is a part of +# another product. + +# File manipulations (create, read, write, etc.) +module file + +intrude import stream +intrude import ropes +import string_search +import time + +in "C Header" `{ + #include + #include + #include + #include + #include + #include + #include + #include +`} + +# File Abstract Stream +abstract class FStream + super IOS + # The path of the file. + var path: nullable String = null + + # The FILE *. + private var file: nullable NativeFile = null + + fun file_stat: FileStat do return _file.file_stat + + # File descriptor of this file + fun fd: Int do return _file.fileno +end + +# File input stream +class IFStream + super FStream + super BufferedIStream + super PollableIStream + # Misc + + # Open the same file again. + # The original path is reused, therefore the reopened file can be a different file. + fun reopen + do + if not eof and not _file.address_is_null then close + _file = new NativeFile.io_open_read(path.to_cstring) + if _file.address_is_null then + last_error = new IOError("Error: Opening file at '{path.as(not null)}' failed with '{sys.errno.strerror}'") + end_reached = true + return + end + end_reached = false + _buffer_pos = 0 + _buffer.clear + end + + redef fun close + do + if _file.address_is_null then return + var i = _file.io_close + _buffer.clear + end_reached = true + end + + redef fun fill_buffer + do + var nb = _file.io_read(_buffer.items, _buffer.capacity) + if nb <= 0 then + end_reached = true + nb = 0 + end + _buffer.length = nb + _buffer_pos = 0 + end + # End of file? + redef var end_reached: Bool = false + + # Open the file at `path` for reading. + init open(path: String) + do + self.path = path + prepare_buffer(10) + _file = new NativeFile.io_open_read(path.to_cstring) + if _file.address_is_null then + last_error = new IOError("Error: Opening file at '{path}' failed with '{sys.errno.strerror}'") + end_reached = true + end + end + + init from_fd(fd: Int) do + self.path = "" + prepare_buffer(10) + _file = fd_to_stream(fd, read_only) + if _file.address_is_null then + last_error = new IOError("Error: Converting fd {fd} to stream failed with '{sys.errno.strerror}'") + end_reached = true + end + end +end + +# File output stream +class OFStream + super FStream + super OStream + + redef fun write(s) + do + if last_error != null then return + if not _is_writable then + last_error = new IOError("Cannot write to non-writable stream") + return + end + if s isa FlatText then + write_native(s.to_cstring, s.length) + else + for i in s.substrings do write_native(i.to_cstring, i.length) + end + end + + redef fun close + do + if _file.address_is_null then + last_error = new IOError("Cannot close non-existing write stream") + _is_writable = false + return + end + var i = _file.io_close + _is_writable = false + end + redef var is_writable = false + + # Write `len` bytes from `native`. + private fun write_native(native: NativeString, len: Int) + do + if last_error != null then return + if not _is_writable then + last_error = new IOError("Cannot write to non-writable stream") + return + end + if _file.address_is_null then + last_error = new IOError("Writing on a null stream") + _is_writable = false + return + end + var err = _file.io_write(native, len) + if err != len then + # Big problem + last_error = new IOError("Problem in writing : {err} {len} \n") + end + end + + # Open the file at `path` for writing. + init open(path: String) + do + _file = new NativeFile.io_open_write(path.to_cstring) + if _file.address_is_null then + last_error = new IOError("Error: Opening file at '{path}' failed with '{sys.errno.strerror}'") + self.path = path + is_writable = false + end + self.path = path + _is_writable = true + end + + # Creates a new File stream from a file descriptor + init from_fd(fd: Int) do + self.path = "" + _file = fd_to_stream(fd, wipe_write) + _is_writable = true + if _file.address_is_null then + last_error = new IOError("Error: Opening stream from file descriptor {fd} failed with '{sys.errno.strerror}'") + _is_writable = false + end + end +end + +redef interface Object + + private fun read_only: NativeString do return "r".to_cstring + + private fun wipe_write: NativeString do return "w".to_cstring + + private fun fd_to_stream(fd: Int, mode: NativeString): NativeFile `{ + return fdopen(fd, mode); + `} + + # returns first available stream to read or write to + # return null on interruption (possibly a signal) + protected fun poll( streams : Sequence[FStream] ) : nullable FStream + do + var in_fds = new Array[Int] + var out_fds = new Array[Int] + var fd_to_stream = new HashMap[Int,FStream] + for s in streams do + var fd = s.fd + if s isa IFStream then in_fds.add( fd ) + if s isa OFStream then out_fds.add( fd ) + + fd_to_stream[fd] = s + end + + var polled_fd = intern_poll( in_fds, out_fds ) + + if polled_fd == null then + return null + else + return fd_to_stream[polled_fd] + end + end + + private fun intern_poll(in_fds: Array[Int], out_fds: Array[Int]) : nullable Int is extern import Array[Int].length, Array[Int].[], Int.as(nullable Int) `{ + int in_len, out_len, total_len; + struct pollfd *c_fds; + sigset_t sigmask; + int i; + int first_polled_fd = -1; + int result; + + in_len = Array_of_Int_length( in_fds ); + out_len = Array_of_Int_length( out_fds ); + total_len = in_len + out_len; + c_fds = malloc( sizeof(struct pollfd) * total_len ); + + /* input streams */ + for ( i=0; i 0 ) { + /* analyse results */ + for ( i=0; i 0 and self.chars[l] == '/' do l -= 1 # remove all trailing `/` + if l == 0 then return "/" + var pos = chars.last_index_of_from('/', l) + var n = self + if pos >= 0 then + n = substring(pos+1, l-pos) + end + return n.strip_extension(ext) + end + + # Extract the dirname of a path + # + # assert "/path/to/a_file.ext".dirname == "/path/to" + # assert "path/to/a_file.ext".dirname == "path/to" + # assert "path/to".dirname == "path" + # assert "path/to/".dirname == "path" + # assert "path".dirname == "." + # assert "/path".dirname == "/" + # assert "/".dirname == "/" + # assert "".dirname == "." + fun dirname: String + do + var l = length - 1 # Index of the last char + while l > 0 and self.chars[l] == '/' do l -= 1 # remove all trailing `/` + var pos = chars.last_index_of_from('/', l) + if pos > 0 then + return substring(0, pos) + else if pos == 0 then + return "/" + else + return "." + end + end + + # Return the canonicalized absolute pathname (see POSIX function `realpath`) + fun realpath: String do + var cs = to_cstring.file_realpath + var res = cs.to_s_with_copy + # cs.free_malloc # FIXME memory leak + return res + end + + # Simplify a file path by remove useless ".", removing "//", and resolving ".." + # ".." are not resolved if they start the path + # starting "/" is not removed + # trainling "/" is removed + # + # Note that the method only wonrk on the string: + # * no I/O access is performed + # * the validity of the path is not checked + # + # assert "some/./complex/../../path/from/../to/a////file//".simplify_path == "path/to/a/file" + # assert "../dir/file".simplify_path == "../dir/file" + # assert "dir/../../".simplify_path == ".." + # assert "dir/..".simplify_path == "." + # assert "//absolute//path/".simplify_path == "/absolute/path" + # assert "//absolute//../".simplify_path == "/" + fun simplify_path: String + do + var a = self.split_with("/") + var a2 = new Array[String] + for x in a do + if x == "." then continue + if x == "" and not a2.is_empty then continue + if x == ".." and not a2.is_empty and a2.last != ".." then + a2.pop + continue + end + a2.push(x) + end + if a2.is_empty then return "." + if a2.length == 1 and a2.first == "" then return "/" + return a2.join("/") + end + + # Correctly join two path using the directory separator. + # + # Using a standard "{self}/{path}" does not work in the following cases: + # + # * `self` is empty. + # * `path` ends with `'/'`. + # * `path` starts with `'/'`. + # + # This method ensures that the join is valid. + # + # assert "hello".join_path("world") == "hello/world" + # assert "hel/lo".join_path("wor/ld") == "hel/lo/wor/ld" + # assert "".join_path("world") == "world" + # assert "hello".join_path("/world") == "/world" + # assert "hello/".join_path("world") == "hello/world" + # assert "hello/".join_path("/world") == "/world" + # + # Note: You may want to use `simplify_path` on the result. + # + # Note: This method works only with POSIX paths. + fun join_path(path: String): String + do + if path.is_empty then return self + if self.is_empty then return path + if path.chars[0] == '/' then return path + if self.last == '/' then return "{self}{path}" + return "{self}/{path}" + end + + # Convert the path (`self`) to a program name. + # + # Ensure the path (`self`) will be treated as-is by POSIX shells when it is + # used as a program name. In order to do that, prepend `./` if needed. + # + # assert "foo".to_program_name == "./foo" + # assert "/foo".to_program_name == "/foo" + # assert "".to_program_name == "./" # At least, your shell will detect the error. + fun to_program_name: String do + if self.has_prefix("/") then + return self + else + return "./{self}" + end + end + + # Alias for `join_path` + # + # assert "hello" / "world" == "hello/world" + # assert "hel/lo" / "wor/ld" == "hel/lo/wor/ld" + # assert "" / "world" == "world" + # assert "/hello" / "/world" == "/world" + # + # This operator is quite useful for chaining changes of path. + # The next one being relative to the previous one. + # + # var a = "foo" + # var b = "/bar" + # var c = "baz/foobar" + # assert a/b/c == "/bar/baz/foobar" + fun /(path: String): String do return join_path(path) + + # Returns the relative path needed to go from `self` to `dest`. + # + # assert "/foo/bar".relpath("/foo/baz") == "../baz" + # assert "/foo/bar".relpath("/baz/bar") == "../../baz/bar" + # + # If `self` or `dest` is relative, they are considered relatively to `getcwd`. + # + # In some cases, the result is still independent of the current directory: + # + # assert "foo/bar".relpath("..") == "../../.." + # + # In other cases, parts of the current directory may be exhibited: + # + # var p = "../foo/bar".relpath("baz") + # var c = getcwd.basename("") + # assert p == "../../{c}/baz" + # + # For path resolution independent of the current directory (eg. for paths in URL), + # or to use an other starting directory than the current directory, + # just force absolute paths: + # + # var start = "/a/b/c/d" + # var p2 = (start/"../foo/bar").relpath(start/"baz") + # assert p2 == "../../d/baz" + # + # + # Neither `self` or `dest` has to be real paths or to exist in directories since + # the resolution is only done with string manipulations and without any access to + # the underlying file system. + # + # If `self` and `dest` are the same directory, the empty string is returned: + # + # assert "foo".relpath("foo") == "" + # assert "foo/../bar".relpath("bar") == "" + # + # The empty string and "." designate both the current directory: + # + # assert "".relpath("foo/bar") == "foo/bar" + # assert ".".relpath("foo/bar") == "foo/bar" + # assert "foo/bar".relpath("") == "../.." + # assert "/" + "/".relpath(".") == getcwd + fun relpath(dest: String): String + do + var cwd = getcwd + var from = (cwd/self).simplify_path.split("/") + if from.last.is_empty then from.pop # case for the root directory + var to = (cwd/dest).simplify_path.split("/") + if to.last.is_empty then to.pop # case for the root directory + + # Remove common prefixes + while not from.is_empty and not to.is_empty and from.first == to.first do + from.shift + to.shift + end + + # Result is going up in `from` with ".." then going down following `to` + var from_len = from.length + if from_len == 0 then return to.join("/") + var up = "../"*(from_len-1) + ".." + if to.is_empty then return up + var res = up + "/" + to.join("/") + return res + end + + # Create a directory (and all intermediate directories if needed) + fun mkdir + do + var dirs = self.split_with("/") + var path = new FlatBuffer + if dirs.is_empty then return + if dirs[0].is_empty then + # it was a starting / + path.add('/') + end + for d in dirs do + if d.is_empty then continue + path.append(d) + path.add('/') + path.to_s.to_cstring.file_mkdir + end + end + + # Delete a directory and all of its content, return `true` on success + # + # Does not go through symbolic links and may get stuck in a cycle if there + # is a cycle in the filesystem. + fun rmdir: Bool + do + var ok = true + for file in self.files do + var file_path = self.join_path(file) + var stat = file_path.file_lstat + if stat.is_dir then + ok = file_path.rmdir and ok + else + ok = file_path.file_delete and ok + end + stat.free + end + + # Delete the directory itself + if ok then to_cstring.rmdir + + return ok + end + + # Change the current working directory + # + # "/etc".chdir + # assert getcwd == "/etc" + # "..".chdir + # assert getcwd == "/" + # + # TODO: errno + fun chdir do to_cstring.file_chdir + + # Return right-most extension (without the dot) + # + # Only the last extension is returned. + # There is no special case for combined extensions. + # + # assert "file.txt".file_extension == "txt" + # assert "file.tar.gz".file_extension == "gz" + # + # For file without extension, `null` is returned. + # Hoever, for trailing dot, `""` is returned. + # + # assert "file".file_extension == null + # assert "file.".file_extension == "" + # + # The starting dot of hidden files is never considered. + # + # assert ".file.txt".file_extension == "txt" + # assert ".file".file_extension == null + fun file_extension: nullable String + do + var last_slash = chars.last_index_of('.') + if last_slash > 0 then + return substring( last_slash+1, length ) + else + return null + end + end + + # returns files contained within the directory represented by self + fun files : Set[ String ] is extern import HashSet[String], HashSet[String].add, NativeString.to_s, String.to_cstring, HashSet[String].as(Set[String]) `{ + char *dir_path; + DIR *dir; + + dir_path = String_to_cstring( recv ); + if ((dir = opendir(dir_path)) == NULL) + { + perror( dir_path ); + exit( 1 ); + } + else + { + HashSet_of_String results; + String file_name; + struct dirent *de; + + results = new_HashSet_of_String(); + + while ( ( de = readdir( dir ) ) != NULL ) + if ( strcmp( de->d_name, ".." ) != 0 && + strcmp( de->d_name, "." ) != 0 ) + { + file_name = NativeString_to_s( strdup( de->d_name ) ); + HashSet_of_String_add( results, file_name ); + } + + closedir( dir ); + return HashSet_of_String_as_Set_of_String( results ); + } + `} +end + +redef class NativeString + private fun file_exists: Bool is extern "string_NativeString_NativeString_file_exists_0" + private fun file_stat: FileStat is extern "string_NativeString_NativeString_file_stat_0" + private fun file_lstat: FileStat `{ + struct stat* stat_element; + int res; + stat_element = malloc(sizeof(struct stat)); + res = lstat(recv, stat_element); + if (res == -1) return NULL; + return stat_element; + `} + private fun file_mkdir: Bool is extern "string_NativeString_NativeString_file_mkdir_0" + private fun rmdir: Bool `{ return rmdir(recv); `} + private fun file_delete: Bool is extern "string_NativeString_NativeString_file_delete_0" + private fun file_chdir is extern "string_NativeString_NativeString_file_chdir_0" + private fun file_realpath: NativeString is extern "file_NativeString_realpath" +end + +# This class is system dependent ... must reify the vfs +extern class FileStat `{ struct stat * `} + # Returns the permission bits of file + fun mode: Int is extern "file_FileStat_FileStat_mode_0" + # Returns the last access time + fun atime: Int is extern "file_FileStat_FileStat_atime_0" + # Returns the last status change time + fun ctime: Int is extern "file_FileStat_FileStat_ctime_0" + # Returns the last modification time + fun mtime: Int is extern "file_FileStat_FileStat_mtime_0" + # Returns the size + fun size: Int is extern "file_FileStat_FileStat_size_0" + + # Returns true if it is a regular file (not a device file, pipe, sockect, ...) + fun is_reg: Bool `{ return S_ISREG(recv->st_mode); `} + # Returns true if it is a directory + fun is_dir: Bool `{ return S_ISDIR(recv->st_mode); `} + # Returns true if it is a character device + fun is_chr: Bool `{ return S_ISCHR(recv->st_mode); `} + # Returns true if it is a block device + fun is_blk: Bool `{ return S_ISBLK(recv->st_mode); `} + # Returns true if the type is fifo + fun is_fifo: Bool `{ return S_ISFIFO(recv->st_mode); `} + # Returns true if the type is a link + fun is_lnk: Bool `{ return S_ISLNK(recv->st_mode); `} + # Returns true if the type is a socket + fun is_sock: Bool `{ return S_ISSOCK(recv->st_mode); `} +end + +# Instance of this class are standard FILE * pointers +private extern class NativeFile `{ FILE* `} + fun io_read(buf: NativeString, len: Int): Int is extern "file_NativeFile_NativeFile_io_read_2" + fun io_write(buf: NativeString, len: Int): Int is extern "file_NativeFile_NativeFile_io_write_2" + fun io_close: Int is extern "file_NativeFile_NativeFile_io_close_0" + fun file_stat: FileStat is extern "file_NativeFile_NativeFile_file_stat_0" + fun fileno: Int `{ return fileno(recv); `} + + new io_open_read(path: NativeString) is extern "file_NativeFileCapable_NativeFileCapable_io_open_read_1" + new io_open_write(path: NativeString) is extern "file_NativeFileCapable_NativeFileCapable_io_open_write_1" + new native_stdin is extern "file_NativeFileCapable_NativeFileCapable_native_stdin_0" + new native_stdout is extern "file_NativeFileCapable_NativeFileCapable_native_stdout_0" + new native_stderr is extern "file_NativeFileCapable_NativeFileCapable_native_stderr_0" +end + +redef class Sys + + # Standard input + var stdin: PollableIStream = new Stdin is protected writable + + # Standard output + var stdout: OStream = new Stdout is protected writable + + # Standard output for errors + var stderr: OStream = new Stderr is protected writable + +end + +# Print `objects` on the standard output (`stdout`). +protected fun printn(objects: Object...) +do + sys.stdout.write(objects.to_s) +end + +# Print an `object` on the standard output (`stdout`) and add a newline. +protected fun print(object: Object) +do + sys.stdout.write(object.to_s) + sys.stdout.write("\n") +end + +# Read a character from the standard input (`stdin`). +protected fun getc: Char +do + return sys.stdin.read_char.ascii +end + +# Read a line from the standard input (`stdin`). +protected fun gets: String +do + return sys.stdin.read_line +end + +# Return the working (current) directory +protected fun getcwd: String do return file_getcwd.to_s +private fun file_getcwd: NativeString is extern "string_NativeString_NativeString_file_getcwd_0" diff --git a/samples/Nit/meetup.nit b/samples/Nit/meetup.nit new file mode 100644 index 00000000..e5d1f561 --- /dev/null +++ b/samples/Nit/meetup.nit @@ -0,0 +1,376 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License + +# Shows a meetup and allows to modify its participants +module meetup + +import opportunity_model +import boilerplate +import welcome +import template + +# Shows a meetup and allows to modify its participants +class OpportunityMeetupPage + super OpportunityPage + + # Meetup the page is supposed to show + var meetup: nullable Meetup = null + # Answer mode for the meetup + var mode = 0 + + init from_id(id: String) do + var db = new OpportunityDB.open("opportunity") + meetup = db.find_meetup_by_id(id) + db.close + if meetup != null then mode = meetup.answer_mode + init + end + + init do + header.page_js = "mode = {mode};\n" + header.page_js += """ + function update_scores(){ + var anss = $('.answer'); + var count = {}; + var scores = {}; + var answers = []; + var maxscore = 0; + for(i=0; i < anss.length; i++){ + var incscore = 0; + var inccount = 0; + var idparts = anss[i].id.split("_"); + var ansid = idparts[1]; + var html = anss[i].innerHTML; + if(html === "

"){ + inccount = 1; + incscore = 2; + }else if(html === "
"){ + incscore = 1; + } + var intansid = parseInt(ansid) + if(answers.indexOf(intansid) == -1){ + answers.push(intansid); + } + if(ansid in count){ + count[ansid] += inccount; + }else{ + count[ansid] = inccount; + } + if(ansid in scores){ + scores[ansid] += incscore; + }else{ + scores[ansid] = incscore; + } + if(scores[ansid] > maxscore){ + maxscore = scores[ansid]; + } + } + for(i=0; i < answers.length; i++){ + var ansid = answers[i].toString(); + var el = $('#total'+ansid)[0]; + var ins = "
"+count[ansid]; + if(scores[ansid] >= maxscore){ + ins += "
"; + } + ins += "
"; + el.innerHTML = ins; + } + } + function change_answer(ele, id){ + // modify only the currently selected entry + if (in_modification_id != id) return; + + var e = document.getElementById(ele.id); + var i = e.innerHTML; + var ans = true;""" + if mode == 0 then + header.page_js += """ + if(i === "
"){ + ans = 0; + e.innerHTML = "
" + e.style.color = "red"; + }else{ + ans = 1; + e.innerHTML = "
"; + e.style.color = "green"; + }""" + + else + header.page_js += """ + if(i === "
"){ + ans = 1; + e.innerHTML = "
" + e.style.color = "#B8860B"; + }else if(i === "
"){ + ans = 0; + e.innerHTML = "
" + e.style.color = "red"; + }else{ + ans = 2; + e.innerHTML = "
"; + e.style.color = "green"; + }""" + end + header.page_js += """ + var a = ele.id.split('_') + var pid = a[1] + var aid = a[2] + update_scores(); + $.ajax({ + type: "POST", + url: "./rest/answer", + data: { + answer_id: aid, + pers_id: pid, + answer: ans + } + }); + } + function change_temp_answer(ele){ + var e = document.getElementById(ele.id); + var i = e.innerHTML;""" + if mode == 0 then + header.page_js += """ + if(i === "
"){ + e.innerHTML = "
" + e.style.color = "red"; + }else{ + e.innerHTML = "
"; + e.style.color = "green"; + } + """ + else + header.page_js += """ + if(i === "
"){ + e.innerHTML = "
"; + e.style.color = "#B8860B"; + }else if(i === "
"){ + e.innerHTML = "
" + e.style.color = "red"; + }else{ + e.innerHTML = "
"; + e.style.color = "green"; + } + """ + end + header.page_js += """ + update_scores(); + } + function add_part(ele){ + var e = document.getElementById(ele.id); + var pname = document.getElementById("new_name").value; + var arr = e.id.split("_"); + var mid = arr[1]; + var ans = $('#' + ele.id).parent().parent().parent().children(".answer"); + ansmap = {}; + for(i=0;i✔"){ + ansmap[curr.attr('id')] = 1 + }else{ + ansmap[curr.attr('id')] = 0 + }""" + else + header.page_js += """ + if(curr[0].innerHTML === "
"){ + ansmap[curr.attr('id')] = 2 + }else if(curr[0].innerHTML === "
"){ + ansmap[curr.attr('id')] = 1 + }else{ + ansmap[curr.attr('id')] = 0 + }""" + end + header.page_js += """ + } + $.ajax({ + type: "POST", + url: "./rest/meetup/new_pers", + data: { + meetup_id: mid, + persname: pname, + answers: $.param(ansmap) + } + }) + .done(function(data){ + location.reload(); + }) + .fail(function(data){ + //TODO: Notify of failure + }); + } + function remove_people(ele){ + var arr = ele.id.split("_") + var pid = arr[1] + $('#' + ele.id).parent().parent().parent().remove(); + update_scores(); + $.ajax({ + type: "POST", + url: "./rest/people", + data: { + method: "DELETE", + p_id: pid + } + }); + } + // ID of line currently open for modification + var in_modification_id = null; + function modify_people(ele, id){ + if (in_modification_id != null) { + // reset to normal values + $('#modify_'+in_modification_id).text("Modify or delete"); + $('#modify_'+in_modification_id).attr("class", "btn btn-xs btn-warning"); + $('#line_'+in_modification_id).css("background-color", ""); + $('#delete_'+in_modification_id).css("display", "none"); + } + if (in_modification_id != id) { + // activate modifiable mode + $('#modify_'+id).text("Done"); + $('#modify_'+id).attr("class", "btn btn-xs btn-success"); + $('#line_'+id).css("background-color", "LightYellow"); + $('#delete_'+id).show(); + + in_modification_id = id; + } else { + in_modification_id = null; + } + } + """ + end + + redef fun rendering do + if meetup == null then + add((new OpportunityHomePage).write_to_string) + return + end + add header + var db = new OpportunityDB.open("opportunity") + add meetup.to_html(db) + db.close + add footer + end +end + +redef class Meetup + # Build the HTML for `self` + fun to_html(db: OpportunityDB): Streamable do + var t = new Template + t.add """ +
+ + +""" + t.add "" + for i in answers(db) do + t.add "" + end + t.add "" + t.add "" + for i in participants(db) do + i.load_answers(db, self) + t.add "" + t.add "" + for j, k in i.answers do + var color + if answer_mode == 0 then + if k == 1 then + color = "green" + else + color = "red" + end + else + if k == 2 then + color = "green" + else if k == 1 then + color = "#B8860B" + else + color = "red" + end + end + t.add """" + end + t.add """""" + t.add "" + end + t.add """ + + + """ + for i in answers(db) do + t.add "" + end + t.add """ + """ + t.add "" + # Compute score for each answer + var scores = new HashMap[Int, Int] + var maxsc = 0 + for i in answers(db) do + scores[i.id] = i.score(db) + if scores[i.id] > maxsc then maxsc = scores[i.id] + end + t.add """ + + + """ + for i in answers(db) do + t.add """" + end + t.add "" + t.add """ + +""" + t.add "
Participant name" + t.add i.to_s + t.add "
" + t.add i.to_s + t.add """" + t.add "
" + if answer_mode == 0 then + if k == 1 then + t.add "✔" + else + t.add "✘" + end + else + if k == 2 then + t.add "✔" + else if k == 1 then + t.add "❓" + else + t.add "✘" + end + end + t.add "
 """ + t.add """
Total
{{{i.count(db)}}}""" + if scores.has_key(i.id) and scores[i.id] >= maxsc then + t.add """
""" + end + t.add "
" + t.add "
" + return t + end +end diff --git a/samples/Objective-J/AppController.j b/samples/Objective-J/AppController.j new file mode 100644 index 00000000..4870ab75 --- /dev/null +++ b/samples/Objective-J/AppController.j @@ -0,0 +1,434 @@ +// +// AppController.j +// FlickrPhoto +// +// Created by Ross Boucher. +// Copyright 2008 - 2010, 280 North, Inc. All rights reserved. + +@import +@import + +var SliderToolbarItemIdentifier = "SliderToolbarItemIdentifier", + AddToolbarItemIdentifier = "AddToolbarItemIdentifier", + RemoveToolbarItemIdentifier = "RemoveToolbarItemIdentifier"; + +/* + Important note about CPJSONPConnection: CPJSONPConnection is ONLY for JSONP APIs. + If aren't sure you NEED JSONP (see http://ajaxian.com/archives/jsonp-json-with-padding ), + you most likely don't want to use CPJSONPConnection, but rather the more standard + CPURLConnection. CPJSONPConnection is designed for cross-domain + connections, and if you are making requests to the same domain (as most web + applications do), you do not need it. +*/ + +@implementation AppController : CPObject +{ + CPString lastIdentifier; + CPDictionary photosets; + + CPCollectionView listCollectionView; + CPCollectionView photosCollectionView; +} + +- (void)applicationDidFinishLaunching:(CPNotification)aNotification +{ + //the first thing we need to do is create a window to take up the full screen + //we'll also create a toolbar to go with it, and grab its size for future reference + + var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask], + contentView = [theWindow contentView], + toolbar = [[CPToolbar alloc] initWithIdentifier:"Photos"], + bounds = [contentView bounds]; + + //we tell the toolbar that we want to be its delegate and attach it to theWindow + [toolbar setDelegate:self]; + [toolbar setVisible:true]; + [theWindow setToolbar:toolbar]; + + photosets = [CPDictionary dictionary]; //storage for our sets of photos return from Flickr + + //now we create a scroll view to contain the list of collections of photos (photosets) + //inside the scroll view, we'll place our collection view, which manages a collection of "cells" + //each cell will represent one photo collection, and choosing cells will select that collection + + var listScrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 0, 200, CGRectGetHeight(bounds) - 58)]; + [listScrollView setAutohidesScrollers:YES]; + [listScrollView setAutoresizingMask:CPViewHeightSizable]; + [[listScrollView contentView] setBackgroundColor:[CPColor colorWithRed:213.0 / 255.0 green:221.0 / 255.0 blue:230.0 / 255.0 alpha:1.0]]; + + //we create the collection view cells by creating a single prototype (CPCollectionViewItem) and setting its view. + //the CPCollectionView class will then duplicate this item as many times as it needs + + var photosListItem = [[CPCollectionViewItem alloc] init]; + [photosListItem setView:[[PhotosListCell alloc] initWithFrame:CGRectMakeZero()]]; + + listCollectionView = [[CPCollectionView alloc] initWithFrame:CGRectMake(0, 0, 200, 0)]; + + [listCollectionView setDelegate:self]; //we want delegate methods + [listCollectionView setItemPrototype:photosListItem]; //set the item prototype + + [listCollectionView setMinItemSize:CGSizeMake(20.0, 45.0)]; + [listCollectionView setMaxItemSize:CGSizeMake(1000.0, 45.0)]; + [listCollectionView setMaxNumberOfColumns:1]; //setting a single column will make this appear as a vertical list + + [listCollectionView setVerticalMargin:0.0]; + [listCollectionView setAutoresizingMask:CPViewWidthSizable]; + + //finally, we put our collection view inside the scroll view as it's document view, so it can be scrolled + [listScrollView setDocumentView:listCollectionView]; + + //and we add it to the window's content view, so it will show up on the screen + [contentView addSubview:listScrollView]; + + //repeat the process with another collection view for the actual photos + //this time we'll use a different view for the prototype (PhotoCell) + + var photoItem = [[CPCollectionViewItem alloc] init]; + [photoItem setView:[[PhotoCell alloc] initWithFrame:CGRectMake(0, 0, 150, 150)]]; + + var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(200, 0, CGRectGetWidth(bounds) - 200, CGRectGetHeight(bounds) - 58)]; + + photosCollectionView = [[CPCollectionView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(bounds) - 200, 0)]; + + [photosCollectionView setDelegate:self]; + [photosCollectionView setItemPrototype:photoItem]; + + [photosCollectionView setMinItemSize:CGSizeMake(150, 150)]; + [photosCollectionView setMaxItemSize:CGSizeMake(150, 150)]; + [photosCollectionView setAutoresizingMask:CPViewWidthSizable]; + + [scrollView setAutoresizingMask:CPViewHeightSizable | CPViewWidthSizable]; + [scrollView setDocumentView:photosCollectionView]; + [scrollView setAutohidesScrollers:YES]; + + [[scrollView contentView] setBackgroundColor:[CPColor colorWithCalibratedWhite:0.25 alpha:1.0]]; + + [contentView addSubview:scrollView]; + + //bring forward the window to display it + [theWindow orderFront:self]; + + //get the most interesting photos on flickr + var request = [CPURLRequest requestWithURL:"http://www.flickr.com/services/rest/?method=flickr.interestingness.getList&per_page=20&format=json&api_key=ca4dd89d3dfaeaf075144c3fdec76756"]; + + // see important note about CPJSONPConnection above + var connection = [CPJSONPConnection sendRequest:request callback:"jsoncallback" delegate:self]; + + lastIdentifier = "Interesting Photos"; +} + +- (void)add:(id)sender +{ + var string = prompt("Enter a tag to search Flickr for photos."); + + if (string) + { + //create a new request for the photos with the tag returned from the javascript prompt + var request = [CPURLRequest requestWithURL:"http://www.flickr.com/services/rest/?"+ + "method=flickr.photos.search&tags="+encodeURIComponent(string)+ + "&media=photos&machine_tag_mode=any&per_page=20&format=json&api_key=ca4dd89d3dfaeaf075144c3fdec76756"]; + + // see important note about CPJSONPConnection above + [CPJSONPConnection sendRequest:request callback:"jsoncallback" delegate:self]; + + lastIdentifier = string; + } +} + +- (void)remove:(id)sender +{ + //remove this photo + [self removeImageListWithIdentifier:[[photosets allKeys] objectAtIndex:[[listCollectionView selectionIndexes] firstIndex]]]; +} + +- (void)addImageList:(CPArray)images withIdentifier:(CPString)aString +{ + [photosets setObject:images forKey:aString]; + + [listCollectionView setContent:[[photosets allKeys] copy]]; + [listCollectionView setSelectionIndexes:[CPIndexSet indexSetWithIndex:[[photosets allKeys] indexOfObject:aString]]]; +} + +- (void)removeImageListWithIdentifier:(CPString)aString +{ + var nextIndex = MAX([[listCollectionView content] indexOfObject:aString] - 1, 0); + + [photosets removeObjectForKey:aString]; + + [listCollectionView setContent:[[photosets allKeys] copy]]; + [listCollectionView setSelectionIndexes:[CPIndexSet indexSetWithIndex:nextIndex]]; +} + +- (void)adjustImageSize:(id)sender +{ + var newSize = [sender value]; + + [photosCollectionView setMinItemSize:CGSizeMake(newSize, newSize)]; + [photosCollectionView setMaxItemSize:CGSizeMake(newSize, newSize)]; +} + +- (void)collectionViewDidChangeSelection:(CPCollectionView)aCollectionView +{ + if (aCollectionView == listCollectionView) + { + var listIndex = [[listCollectionView selectionIndexes] firstIndex]; + + if (listIndex === CPNotFound) + return; + + var key = [listCollectionView content][listIndex]; + + [photosCollectionView setContent:[photosets objectForKey:key]]; + [photosCollectionView setSelectionIndexes:[CPIndexSet indexSet]]; + } +} + +- (void)connection:(CPJSONPConnection)aConnection didReceiveData:(CPString)data +{ + //this method is called when the network request returns. the data is the returned + //information from flickr. we set the array of photo urls as the data to our collection view + + [self addImageList:data.photos.photo withIdentifier:lastIdentifier]; +} + +- (void)connection:(CPJSONPConnection)aConnection didFailWithError:(CPString)error +{ + alert(error); //a network error occurred +} + +//these two methods are the toolbar delegate methods, and tell the toolbar what it should display to the user + +- (CPArray)toolbarAllowedItemIdentifiers:(CPToolbar)aToolbar +{ + return [self toolbarDefaultItemIdentifiers:aToolbar]; +} + +- (CPArray)toolbarDefaultItemIdentifiers:(CPToolbar)aToolbar +{ + return [AddToolbarItemIdentifier, RemoveToolbarItemIdentifier, CPToolbarFlexibleSpaceItemIdentifier, SliderToolbarItemIdentifier]; +} + +//this delegate method returns the actual toolbar item for the given identifier + +- (CPToolbarItem)toolbar:(CPToolbar)aToolbar itemForItemIdentifier:(CPString)anItemIdentifier willBeInsertedIntoToolbar:(BOOL)aFlag +{ + var toolbarItem = [[CPToolbarItem alloc] initWithItemIdentifier:anItemIdentifier]; + + if (anItemIdentifier == SliderToolbarItemIdentifier) + { + [toolbarItem setView:[[PhotoResizeView alloc] initWithFrame:CGRectMake(0, 0, 180, 32)]]; + [toolbarItem setMinSize:CGSizeMake(180, 32)]; + [toolbarItem setMaxSize:CGSizeMake(180, 32)]; + [toolbarItem setLabel:"Scale"]; + } + else if (anItemIdentifier == AddToolbarItemIdentifier) + { + var image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle mainBundle] pathForResource:"add.png"] size:CPSizeMake(30, 25)], + highlighted = [[CPImage alloc] initWithContentsOfFile:[[CPBundle mainBundle] pathForResource:"addHighlighted.png"] size:CPSizeMake(30, 25)]; + + [toolbarItem setImage:image]; + [toolbarItem setAlternateImage:highlighted]; + + [toolbarItem setTarget:self]; + [toolbarItem setAction:@selector(add:)]; + [toolbarItem setLabel:"Add Photo List"]; + + [toolbarItem setMinSize:CGSizeMake(32, 32)]; + [toolbarItem setMaxSize:CGSizeMake(32, 32)]; + } + else if (anItemIdentifier == RemoveToolbarItemIdentifier) + { + var image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle mainBundle] pathForResource:"remove.png"] size:CPSizeMake(30, 25)], + highlighted = [[CPImage alloc] initWithContentsOfFile:[[CPBundle mainBundle] pathForResource:"removeHighlighted.png"] size:CPSizeMake(30, 25)]; + + [toolbarItem setImage:image]; + [toolbarItem setAlternateImage:highlighted]; + + [toolbarItem setTarget:self]; + [toolbarItem setAction:@selector(remove:)]; + [toolbarItem setLabel:"Remove Photo List"]; + + [toolbarItem setMinSize:CGSizeMake(32, 32)]; + [toolbarItem setMaxSize:CGSizeMake(32, 32)]; + } + + return toolbarItem; +} + +@end + +/* + This code demonstrates how to add a category to an existing class. + In this case, we are adding the class method +flickr_labelWithText: to + the CPTextField class. Later on, we can call [CPTextField flickr_labelWithText:"foo"] + to return a new text field with the string foo. + Best practices suggest prefixing category methods with your unique prefix, to prevent collisions. +*/ + +@implementation CPTextField (CreateLabel) + ++ (CPTextField)flickr_labelWithText:(CPString)aString +{ + var label = [[CPTextField alloc] initWithFrame:CGRectMakeZero()]; + + [label setStringValue:aString]; + [label sizeToFit]; + [label setTextShadowColor:[CPColor whiteColor]]; + [label setTextShadowOffset:CGSizeMake(0, 1)]; + + return label; +} + +@end + +// This class wraps our slider + labels combo + +@implementation PhotoResizeView : CPView +{ +} + +- (id)initWithFrame:(CGRect)aFrame +{ + self = [super initWithFrame:aFrame]; + + var slider = [[CPSlider alloc] initWithFrame:CGRectMake(30, CGRectGetHeight(aFrame) / 2.0 - 8, CGRectGetWidth(aFrame) - 65, 24)]; + + [slider setMinValue:50.0]; + [slider setMaxValue:250.0]; + [slider setIntValue:150.0]; + [slider setAction:@selector(adjustImageSize:)]; + + [self addSubview:slider]; + + var label = [CPTextField flickr_labelWithText:"50"]; + [label setFrameOrigin:CGPointMake(0, CGRectGetHeight(aFrame) / 2.0 - 4.0)]; + [self addSubview:label]; + + label = [CPTextField flickr_labelWithText:"250"]; + [label setFrameOrigin:CGPointMake(CGRectGetWidth(aFrame) - CGRectGetWidth([label frame]), CGRectGetHeight(aFrame) / 2.0 - 4.0)]; + [self addSubview:label]; + + return self; +} + +@end + +// This class displays a single photo collection inside our list of photo collecitions + +@implementation PhotosListCell : CPView +{ + CPTextField label; + CPView highlightView; +} + +- (void)setRepresentedObject:(JSObject)anObject +{ + if (!label) + { + label = [[CPTextField alloc] initWithFrame:CGRectInset([self bounds], 4, 4)]; + + [label setFont:[CPFont systemFontOfSize:16.0]]; + [label setTextShadowColor:[CPColor whiteColor]]; + [label setTextShadowOffset:CGSizeMake(0, 1)]; + + [self addSubview:label]; + } + + [label setStringValue:anObject]; + [label sizeToFit]; + + [label setFrameOrigin:CGPointMake(10,CGRectGetHeight([label bounds]) / 2.0)]; +} + +- (void)setSelected:(BOOL)flag +{ + if (!highlightView) + { + highlightView = [[CPView alloc] initWithFrame:CGRectCreateCopy([self bounds])]; + [highlightView setBackgroundColor:[CPColor blueColor]]; + } + + if (flag) + { + [self addSubview:highlightView positioned:CPWindowBelow relativeTo:label]; + [label setTextColor:[CPColor whiteColor]]; + [label setTextShadowColor:[CPColor blackColor]]; + } + else + { + [highlightView removeFromSuperview]; + [label setTextColor:[CPColor blackColor]]; + [label setTextShadowColor:[CPColor whiteColor]]; + } +} + +@end + +// This class displays a single photo from our collection + +@implementation PhotoCell : CPView +{ + CPImage image; + CPImageView imageView; + CPView highlightView; +} + +- (void)setRepresentedObject:(JSObject)anObject +{ + if (!imageView) + { + imageView = [[CPImageView alloc] initWithFrame:CGRectMakeCopy([self bounds])]; + [imageView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; + [imageView setImageScaling:CPScaleProportionally]; + [imageView setHasShadow:YES]; + [self addSubview:imageView]; + } + + [image setDelegate:nil]; + + image = [[CPImage alloc] initWithContentsOfFile:thumbForFlickrPhoto(anObject)]; + + [image setDelegate:self]; + + if ([image loadStatus] == CPImageLoadStatusCompleted) + [imageView setImage:image]; + else + [imageView setImage:nil]; +} + +- (void)imageDidLoad:(CPImage)anImage +{ + [imageView setImage:anImage]; +} + +- (void)setSelected:(BOOL)flag +{ + if (!highlightView) + { + highlightView = [[CPView alloc] initWithFrame:[self bounds]]; + [highlightView setBackgroundColor:[CPColor colorWithCalibratedWhite:0.8 alpha:0.6]]; + [highlightView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; + } + + if (flag) + { + [highlightView setFrame:[self bounds]]; + [self addSubview:highlightView positioned:CPWindowBelow relativeTo:imageView]; + } + else + [highlightView removeFromSuperview]; +} + +@end + +// helper javascript functions for turning a Flickr photo object into a URL for getting the image + +function urlForFlickrPhoto(photo) +{ + return "http://farm" + photo.farm + ".static.flickr.com/" + photo.server + "/" + photo.id+"_" + photo.secret + ".jpg"; +} + +function thumbForFlickrPhoto(photo) +{ + return "http://farm" + photo.farm + ".static.flickr.com/" + photo.server + "/" + photo.id + "_" + photo.secret + "_m.jpg"; +} \ No newline at end of file diff --git a/samples/Objective-J/LightsOff.j b/samples/Objective-J/LightsOff.j new file mode 100644 index 00000000..70959136 --- /dev/null +++ b/samples/Objective-J/LightsOff.j @@ -0,0 +1,88 @@ +@import +@import +@import +@import +@import "LOBoard.j" + +@implementation LOInfoView : CPView +{ +} + +- (void)drawRect:(CGRect)r +{ + [[CPColor whiteColor] setFill] + var path = [CPBezierPath bezierPath]; + [path appendBezierPathWithRoundedRect:CGRectMake(5, 0, CGRectGetWidth([self bounds]) - 10.0, CGRectGetHeight([self bounds])) xRadius:10 yRadius:10]; + [path fill]; +} + +@end + +@implementation AppController : CPObject +{ +} + +- (CPPanel)initInfoWindow +{ + var infoWindow = [[CPPanel alloc] initWithContentRect:CGRectMake(400, 50, 320, 480) styleMask:CPHUDBackgroundWindowMask | CPResizableWindowMask]; + [infoWindow setFloatingPanel:YES]; + + var _infoContent = [infoWindow contentView], + _iconImage = [[CPImage alloc] initWithContentsOfFile:"Resources/icon.png" size:CPSizeMake(59, 60)], + _iconView = [[CPImageView alloc] initWithFrame:CGRectMake(125, 0, 59, 60)]; + + [_iconView setImage:_iconImage]; + [_infoContent addSubview:_iconView]; + + var _infoView = [[LOInfoView alloc] initWithFrame:CGRectMake(0, 65, 320, 395)], + _webView = [[CPWebView alloc] initWithFrame:CGRectMake(20, 0, 270, 370)]; + + [_webView loadHTMLString:@"

Lights Off

Lights Off is a fantastic game exclusively for iPhone and iPod touch and inspired by Tiger Electronic's 'Lights Out'.

The goal of the game is simply to switch all of the lights off, but it's harder than it looks! Give the first few levels a try in the playable demo to the left.

"]; + + [_infoView addSubview:_webView]; + + [_infoContent addSubview:_infoView]; + + return infoWindow; +} + +- (void)applicationDidFinishLaunching:(CPNotification)aNotification +{ + /* Enable Logging (DEBUG) */ + // CPLogRegister(CPLogPopup); + + var rootWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask]; + [rootWindow setBackgroundColor:[CPColor grayColor]]; + [rootWindow orderFront:self]; + + var infoWindow = [self initInfoWindow], + gameWindow = [[CPPanel alloc] initWithContentRect:CGRectMake(50, 50, 324, 482) styleMask:CPHUDBackgroundWindowMask]; + [gameWindow setFloatingPanel:YES]; + [gameWindow setTitle:@"Lights Off"]; + + contentView = [gameWindow contentView]; + + var _board = [[LOBoard alloc] initWithFrame:CGRectMake(2, 0, 320, 480)], + _bgImage = [[CPImage alloc] initWithContentsOfFile:"Resources/lo-background.png" size:CPSizeMake(320, 480)]; + [_board setImage:_bgImage]; + [_board resetBoard]; + + var _buttonImage = [[CPImage alloc] initWithContentsOfFile:"Resources/button-reset.png" size:CPSizeMake(90, 28)], + _buttonPressImage = [[CPImage alloc] initWithContentsOfFile:"Resources/button-reset-press.png" size:CPSizeMake(90, 28)], + _resetButton = [[CPButton alloc] initWithFrame:CGRectMake(195, 422, 90, 28)]; + + [_resetButton setImage:_buttonImage]; + [_resetButton setAlternateImage:_buttonPressImage]; + [_resetButton setBordered:NO]; + + [contentView addSubview:_board]; + [contentView addSubview:_resetButton]; + + [_resetButton setTarget:_board]; + [_resetButton setAction:@selector(resetBoard)]; + + [gameWindow orderFront:self]; + [infoWindow orderFront:self]; +} + +@end \ No newline at end of file diff --git a/samples/Objective-J/iTunesLayout.j b/samples/Objective-J/iTunesLayout.j new file mode 100644 index 00000000..c1ffb2e9 --- /dev/null +++ b/samples/Objective-J/iTunesLayout.j @@ -0,0 +1,47 @@ + +@import + + +@implementation AppController : CPObject +{ +} + +- (void)applicationDidFinishLaunching:(CPNotification)aNotification +{ + // The end result of this layout will be the kind of master/detail/auxilliary view + // found in iTunes, Mail, and many other apps. + + var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask], + contentView = [theWindow contentView]; + + var navigationArea = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 150.0, CGRectGetHeight([contentView bounds]) - 150.0)]; + + [navigationArea setBackgroundColor:[CPColor redColor]]; + + // This view will grow in height, but stay fixed width attached to the left side of the screen. + [navigationArea setAutoresizingMask:CPViewHeightSizable | CPViewMaxXMargin]; + + [contentView addSubview:navigationArea]; + + var metaDataArea = [[CPView alloc] initWithFrame:CGRectMake(0.0, CGRectGetMaxY([navigationArea frame]), 150.0, 150.0)]; + + [metaDataArea setBackgroundColor:[CPColor greenColor]]; + + // This view will stay the same size in both directions, and fixed to the lower left corner. + [metaDataArea setAutoresizingMask:CPViewMinYMargin | CPViewMaxXMargin]; + + [contentView addSubview:metaDataArea]; + + var contentArea = [[CPView alloc] initWithFrame:CGRectMake(150.0, 0.0, CGRectGetWidth([contentView bounds]) - 150.0, CGRectGetHeight([contentView bounds]))]; + + [contentArea setBackgroundColor:[CPColor blueColor]]; + + // This view will grow in both height an width. + [contentArea setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; + + [contentView addSubview:contentArea]; + + [theWindow orderFront:self]; +} + +@end \ No newline at end of file diff --git a/samples/Oz/example.oz b/samples/Oz/example.oz new file mode 100644 index 00000000..21c206a2 --- /dev/null +++ b/samples/Oz/example.oz @@ -0,0 +1,52 @@ +% You can get a lot of information about Oz by following theses links : +% - http://mozart.github.io/ +% - http://en.wikipedia.org/wiki/Oz_(programming_language) +% There is also a well known book that uses Oz for pedagogical reason : +% - http://mitpress.mit.edu/books/concepts-techniques-and-models-computer-programming +% And there are two courses on edX about 'Paradigms of Computer Programming' that also uses Oz for pedagogical reason : +% - https://www.edx.org/node/2751#.VHijtfl5OSo +% - https://www.edx.org/node/4436#.VHijzfl5OSo +% +% Here is an example of some code written with Oz. + +declare +% Computes the sum of square of the N first integers. +fun {Sum N} + local SumAux in + fun {SumAux N Acc} + if N==0 then Acc + else + {Sum N-1 Acc} + end + end + {SumAux N 0} + end +end + +% Returns true if N is a prime and false otherwize +fun {Prime N} + local PrimeAcc in + fun {PrimeAcc N Acc} + if(N == 1) then false + elseif(Acc == 1) then true + else + if (N mod Acc) == 0 then false + else + {PrimeAcc N Acc-1} + end + end + end + {PrimeAcc N (N div 2)} + end +end + +% Reverse a list using cells and for loop (instead of recursivity) +fun {Reverse L} + local RevList in + RevList = {NewCell nil} + for E in L do + RevList := E|@RevList + end + @RevList + end +end diff --git a/samples/Zephir/filenames/exception.zep.php b/samples/PHP/exception.zep.php similarity index 100% rename from samples/Zephir/filenames/exception.zep.php rename to samples/PHP/exception.zep.php diff --git a/samples/Pascal/cwindirs.pp b/samples/Pascal/cwindirs.pp new file mode 100644 index 00000000..d97895e3 --- /dev/null +++ b/samples/Pascal/cwindirs.pp @@ -0,0 +1,121 @@ + +unit cwindirs; + + + + +interface + +uses + windows, + strings; + +Const + CSIDL_PROGRAMS = $0002; + CSIDL_PERSONAL = $0005; + CSIDL_FAVORITES = $0006; + CSIDL_STARTUP = $0007; + CSIDL_RECENT = $0008; + CSIDL_SENDTO = $0009; + CSIDL_STARTMENU = $000B; + CSIDL_MYMUSIC = $000D; + CSIDL_MYVIDEO = $000E; + CSIDL_DESKTOPDIRECTORY = $0010; + CSIDL_NETHOOD = $0013; + CSIDL_TEMPLATES = $0015; + CSIDL_COMMON_STARTMENU = $0016; + CSIDL_COMMON_PROGRAMS = $0017; + CSIDL_COMMON_STARTUP = $0018; + CSIDL_COMMON_DESKTOPDIRECTORY = $0019; + CSIDL_APPDATA = $001A; + CSIDL_PRINTHOOD = $001B; + CSIDL_LOCAL_APPDATA = $001C; + CSIDL_COMMON_FAVORITES = $001F; + CSIDL_INTERNET_CACHE = $0020; + CSIDL_COOKIES = $0021; + CSIDL_HISTORY = $0022; + CSIDL_COMMON_APPDATA = $0023; + CSIDL_WINDOWS = $0024; + CSIDL_SYSTEM = $0025; + CSIDL_PROGRAM_FILES = $0026; + CSIDL_MYPICTURES = $0027; + CSIDL_PROFILE = $0028; + CSIDL_PROGRAM_FILES_COMMON = $002B; + CSIDL_COMMON_TEMPLATES = $002D; + CSIDL_COMMON_DOCUMENTS = $002E; + CSIDL_COMMON_ADMINTOOLS = $002F; + CSIDL_ADMINTOOLS = $0030; + CSIDL_COMMON_MUSIC = $0035; + CSIDL_COMMON_PICTURES = $0036; + CSIDL_COMMON_VIDEO = $0037; + CSIDL_CDBURN_AREA = $003B; + CSIDL_PROFILES = $003E; + + CSIDL_FLAG_CREATE = $8000; + +Function GetWindowsSpecialDir(ID : Integer) : String; + +implementation + +uses + sysutils; + +Type + PFNSHGetFolderPath = Function(Ahwnd: HWND; Csidl: Integer; Token: THandle; Flags: DWord; Path: PChar): HRESULT; stdcall; + + +var + SHGetFolderPath : PFNSHGetFolderPath = Nil; + CFGDLLHandle : THandle = 0; + +Procedure InitDLL; + +Var + pathBuf: array[0..MAX_PATH-1] of char; + pathLength: Integer; +begin + { Load shfolder.dll using a full path, in order to prevent spoofing (Mantis #18185) + Don't bother loading shell32.dll because shfolder.dll itself redirects SHGetFolderPath + to shell32.dll whenever possible. } + pathLength:=GetSystemDirectory(pathBuf, MAX_PATH); + if (pathLength>0) and (pathLength0) then + begin + Pointer(ShGetFolderPath):=GetProcAddress(CFGDLLHandle,'SHGetFolderPathA'); + If @ShGetFolderPath=nil then + begin + FreeLibrary(CFGDLLHandle); + CFGDllHandle:=0; + end; + end; + end; + If (@ShGetFolderPath=Nil) then + Raise Exception.Create('Could not determine SHGetFolderPath Function'); +end; + +Function GetWindowsSpecialDir(ID : Integer) : String; + +Var + APath : Array[0..MAX_PATH] of char; + +begin + Result:=''; + if (CFGDLLHandle=0) then + InitDLL; + If (SHGetFolderPath<>Nil) then + begin + if SHGetFolderPath(0,ID or CSIDL_FLAG_CREATE,0,0,@APATH[0])=S_OK then + Result:=IncludeTrailingPathDelimiter(StrPas(@APath[0])); + end; +end; + +Initialization +Finalization + if CFGDLLHandle<>0 then + FreeLibrary(CFGDllHandle); +end. + diff --git a/samples/Pascal/gtkextra.pp b/samples/Pascal/gtkextra.pp deleted file mode 100644 index 9f2ebf8c..00000000 --- a/samples/Pascal/gtkextra.pp +++ /dev/null @@ -1,51 +0,0 @@ -{ $Id$ } -{ - --------------------------------------------------------------------------- - gtkextra.pp - GTK(2) widgetset - additional gdk/gtk functions - --------------------------------------------------------------------------- - - This unit contains missing gdk/gtk functions and defines for certain - versions of gtk or fpc. - - --------------------------------------------------------------------------- - - @created(Sun Jan 28th WET 2006) - @lastmod($Date$) - @author(Marc Weustink ) - - ***************************************************************************** - This file is part of the Lazarus Component Library (LCL) - - See the file COPYING.modifiedLGPL.txt, included in this distribution, - for details about the license. - ***************************************************************************** - } - -unit GtkExtra; - -{$mode objfpc}{$H+} - -interface - -{$I gtkdefines.inc} - -{$ifdef gtk1} -{$I gtk1extrah.inc} -{$endif} - -{$ifdef gtk2} -{$I gtk2extrah.inc} -{$endif} - - -implementation - -{$ifdef gtk1} -{$I gtk1extra.inc} -{$endif} - -{$ifdef gtk2} -{$I gtk2extra.inc} -{$endif} - -end. diff --git a/samples/Pascal/large.pp b/samples/Pascal/large.pp new file mode 100644 index 00000000..9e0f4867 --- /dev/null +++ b/samples/Pascal/large.pp @@ -0,0 +1,22 @@ +program large; + + const + max = 100000000; + + type + tlist = array[1..max] of longint; + + var + data : tlist; + i : integer; + +begin + + i := 0; + while(i < max) + do + begin + data[i] := 0; + Writeln(data[i]) + end +end. diff --git a/samples/Pascal/tw27294.pp b/samples/Pascal/tw27294.pp new file mode 100644 index 00000000..34d14f5d --- /dev/null +++ b/samples/Pascal/tw27294.pp @@ -0,0 +1,26 @@ +uses + uw27294; + +var + p : procedure; + +procedure test; + +begin + p:=@test; + writeln('OK'); +end; + +procedure global; +begin + p:=nil; + test; + p(); +end; + +begin + global; + uw27294.global; +end. + + diff --git a/samples/Perl/use5.pl b/samples/Perl/use5.pl new file mode 100644 index 00000000..de7d248c --- /dev/null +++ b/samples/Perl/use5.pl @@ -0,0 +1,3 @@ +use Mojolicious::Lite; +use 5.20.0; +use experimental 'signatures'; diff --git a/samples/Perl6/01-dash-uppercase-i.t b/samples/Perl6/01-dash-uppercase-i.t new file mode 100644 index 00000000..57a5afd0 --- /dev/null +++ b/samples/Perl6/01-dash-uppercase-i.t @@ -0,0 +1,97 @@ +use v6; + +use Test; + +=begin pod + +Test handling of -I. + +Multiple C<-I> switches are supposed to +prepend left-to-right: + + -Ifoo -Ibar + +should make C<@*INC> look like: + + foo + bar + ... + +Duplication of directories on the command line is mirrored +in the C<@*INC> variable, so C will have B +entries C in C<@*INC>. + +=end pod + +# L + +my $fragment = '-e "@*INC.perl.say"'; + +my @tests = ( + 'foo', + 'foo$bar', + 'foo bar$baz', + 'foo$foo', +); + +plan @tests*2; + +diag "Running under $*OS"; + +my ($pugs,$redir) = ($*EXECUTABLE_NAME, ">"); + +if $*OS eq any { + $pugs = 'pugs.exe'; + $redir = '>'; +}; + +sub nonce () { return (".{$*PID}." ~ (1..1000).pick) } + +sub run_pugs ($c) { + my $tempfile = "temp-ex-output" ~ nonce; + my $command = "$pugs $c $redir $tempfile"; + diag $command; + run $command; + my $res = slurp $tempfile; + unlink $tempfile; + return $res; +} + +for @tests -> $t { + my @dirs = split('$',$t); + my $command; + # This should be smarter about quoting + # (currently, this should work for WinNT and Unix shells) + $command = join " ", map { qq["-I$_"] }, @dirs; + my $got = run_pugs( $command ~ " $fragment" ); + $got .= chomp; + + if (substr($got,0,1) ~~ "[") { + # Convert from arrayref to array + $got = substr($got, 1, -1); + }; + + my @got = EVAL $got; + @got = @got[ 0..@dirs-1 ]; + my @expected = @dirs; + + is @got, @expected, "'" ~ @dirs ~ "' works"; + + $command = join " ", map { qq[-I "$_"] }, @dirs; + $got = run_pugs( $command ~ " $fragment" ); + + $got .= chomp; + if (substr($got,0,1) ~~ "[") { + # Convert from arrayref to array + $got = substr($got, 1, -1); + }; + + @got = EVAL $got; + @got = @got[ 0..@dirs-1 ]; + @expected = @dirs; + + is @got, @expected, "'" ~ @dirs ~ "' works (with a space delimiting -I)"; +} + + +# vim: ft=perl6 diff --git a/samples/Perl6/01-parse.t b/samples/Perl6/01-parse.t new file mode 100644 index 00000000..6c81fb04 --- /dev/null +++ b/samples/Perl6/01-parse.t @@ -0,0 +1,223 @@ +use v6; +BEGIN { @*INC.push('lib') }; + +use JSON::Tiny::Grammar; +use Test; + +my @t = + '{}', + '{ }', + ' { } ', + '{ "a" : "b" }', + '{ "a" : null }', + '{ "a" : true }', + '{ "a" : false }', + '{ "a" : { } }', + '[]', + '[ ]', + ' [ ] ', + # stolen from JSON::XS, 18_json_checker.t, and adapted a bit + Q<<[ + "JSON Test Pattern pass1", + {"object with 1 member":["array with 1 element"]}, + {}, + [] + ]>>, + Q<<[1]>>, + Q<<[true]>>, + Q<<[-42]>>, + Q<<[-42,true,false,null]>>, + Q<<{ "integer": 1234567890 }>>, + Q<<{ "real": -9876.543210 }>>, + Q<<{ "e": 0.123456789e-12 }>>, + Q<<{ "E": 1.234567890E+34 }>>, + Q<<{ "": 23456789012E66 }>>, + Q<<{ "zero": 0 }>>, + Q<<{ "one": 1 }>>, + Q<<{ "space": " " }>>, + Q<<{ "quote": "\""}>>, + Q<<{ "backslash": "\\"}>>, + Q<<{ "controls": "\b\f\n\r\t"}>>, + Q<<{ "slash": "/ & \/"}>>, + Q<<{ "alpha": "abcdefghijklmnopqrstuvwyz"}>>, + Q<<{ "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ"}>>, + Q<<{ "digit": "0123456789"}>>, + Q<<{ "0123456789": "digit"}>>, + Q<<{"special": "`1~!@#$%^&*()_+-={':[,]}|;.?"}>>, + Q<<{"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A"}>>, + Q<<{"true": true}>>, + Q<<{"false": false}>>, + Q<<{"null": null}>>, + Q<<{"array":[ ]}>>, + Q<<{"object":{ }}>>, + Q<<{"address": "50 St. James Street"}>>, + Q<<{"url": "http://www.JSON.org/"}>>, + Q<<{"comment": "// /* */": " "}>>, + Q<<{ " s p a c e d " :[1,2 , 3 + +, + +4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7]}>>, + + Q<<{"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}"}>>, + Q<<{"quotes": "" \u0022 %22 0x22 034 ""}>>, + Q<<{ "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" +: "A key can be any string" + }>>, + Q<<[ 0.5 ,98.6 +, +99.44 +, + +1066, +1e1, +0.1e1 + ]>>, + Q<<[1e-1]>>, + Q<<[1e00,2e+00,2e-00,"rosebud"]>>, + Q<<[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]>>, + Q<<{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +} +>>, +# from http://www.json.org/example.html + Q<<{ + "glossary": { + "title": "example glossary", + "GlossDiv": { + "title": "S", + "GlossList": { + "GlossEntry": { + "ID": "SGML", + "SortAs": "SGML", + "GlossTerm": "Standard Generalized Markup Language", + "Acronym": "SGML", + "Abbrev": "ISO 8879:1986", + "GlossDef": { + "para": "A meta-markup language, used to create markup languages such as DocBook.", + "GlossSeeAlso": ["GML", "XML"] + }, + "GlossSee": "markup" + } + } + } + } +} + >>, + Q<<{"menu": { + "id": "file", + "value": "File", + "popup": { + "menuitem": [ + {"value": "New", "onclick": "CreateNewDoc()"}, + {"value": "Open", "onclick": "OpenDoc()"}, + {"value": "Close", "onclick": "CloseDoc()"} + ] + } +}}>>, + Q<<{"widget": { + "debug": "on", + "window": { + "title": "Sample Konfabulator Widget", + "name": "main_window", + "width": 500, + "height": 500 + }, + "image": { + "src": "Images/Sun.png", + "name": "sun1", + "hOffset": 250, + "vOffset": 250, + "alignment": "center" + }, + "text": { + "data": "Click Here", + "size": 36, + "style": "bold", + "name": "text1", + "hOffset": 250, + "vOffset": 100, + "alignment": "center", + "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" + } +}}>>, + ; + +my @n = + '{ ', + '{ 3 : 4 }', + '{ 3 : tru }', # not quite true + '{ "a : false }', # missing quote + # stolen from JSON::XS, 18_json_checker.t + Q<<"A JSON payload should be an object or array, not a string.">>, + Q<<{"Extra value after close": true} "misplaced quoted value">>, + Q<<{"Illegal expression": 1 + 2}>>, + Q<<{"Illegal invocation": alert()}>>, + Q<<{"Numbers cannot have leading zeroes": 013}>>, + Q<<{"Numbers cannot be hex": 0x14}>>, + Q<<["Illegal backslash escape: \x15"]>>, + Q<<[\naked]>>, + Q<<["Illegal backslash escape: \017"]>>, +# skipped: wo don't implement no stinkin' aritifical limits. +# Q<<[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]>>, + Q<<{"Missing colon" null}>>, + Q<<["Unclosed array">>, + Q<<{"Double colon":: null}>>, + Q<<{"Comma instead of colon", null}>>, + Q<<["Colon instead of comma": false]>>, + Q<<["Bad value", truth]>>, + Q<<['single quote']>>, + qq<["\ttab\tcharacter in string "]>, + Q<<["line +break"]>>, + Q<<["line\ +break"]>>, + Q<<[0e]>>, + Q<<{unquoted_key: "keys must be quoted"}>>, + Q<<[0e+]>>, + Q<<[0e+-1]>>, + Q<<{"Comma instead if closing brace": true,>>, + Q<<["mismatch"}>>, + Q<<["extra comma",]>>, + Q<<["double extra comma",,]>>, + Q<<[ , "<-- missing value"]>>, + Q<<["Comma after the close"],>>, + Q<<["Extra close"]]>>, + Q<<{"Extra comma": true,}>>, +; + +plan (+@t) + (+@n); + +my $i = 0; +for @t -> $t { + my $desc = $t; + if $desc ~~ m/\n/ { + $desc .= subst(/\n.*$/, "\\n...[$i]"); + } + my $parsed = 0; + try { + JSON::Tiny::Grammar.parse($t) + and $parsed = 1; + } + ok $parsed, "JSON string «$desc» parsed"; + $i++; +} + +for @n -> $t { + my $desc = $t; + if $desc ~~ m/\n/ { + $desc .= subst(/\n.*$/, "\\n...[$i]"); + } + my $parsed = 0; + try { JSON::Tiny::Grammar.parse($t) and $parsed = 1 }; + nok $parsed, "NOT parsed «$desc»"; + $i++; +} + + +# vim: ft=perl6 + diff --git a/samples/Perl6/A.pm b/samples/Perl6/A.pm new file mode 100644 index 00000000..345e889b --- /dev/null +++ b/samples/Perl6/A.pm @@ -0,0 +1,9 @@ +# used in t/spec/S11-modules/nested.t + +BEGIN { @*INC.push('t/spec/packages') }; + +module A::A { + use A::B; +} + +# vim: ft=perl6 diff --git a/samples/Perl6/ANSIColor.pm b/samples/Perl6/ANSIColor.pm new file mode 100644 index 00000000..87e557cb --- /dev/null +++ b/samples/Perl6/ANSIColor.pm @@ -0,0 +1,148 @@ +use v6; + +module Term::ANSIColor; + +# these will be macros one day, yet macros can't be exported so far +sub RESET is export { "\e[0m" } +sub BOLD is export { "\e[1m" } +sub UNDERLINE is export { "\e[4m" } +sub INVERSE is export { "\e[7m" } +sub BOLD_OFF is export { "\e[22m" } +sub UNDERLINE_OFF is export { "\e[24m" } +sub INVERSE_OFF is export { "\e[27m" } + +my %attrs = + reset => "0", + bold => "1", + underline => "4", + inverse => "7", + black => "30", + red => "31", + green => "32", + yellow => "33", + blue => "34", + magenta => "35", + cyan => "36", + white => "37", + default => "39", + on_black => "40", + on_red => "41", + on_green => "42", + on_yellow => "43", + on_blue => "44", + on_magenta => "45", + on_cyan => "46", + on_white => "47", + on_default => "49"; + +sub color (Str $what) is export { + my @res; + my @a = $what.split(' '); + for @a -> $attr { + if %attrs.exists($attr) { + @res.push: %attrs{$attr} + } else { + die("Invalid attribute name '$attr'") + } + } + return "\e[" ~ @res.join(';') ~ "m"; +} + +sub colored (Str $what, Str $how) is export { + color($how) ~ $what ~ color('reset'); +} + +sub colorvalid (*@a) is export { + for @a -> $el { + return False unless %attrs.exists($el) + } + return True; +} + +sub colorstrip (*@a) is export { + my @res; + for @a -> $str { + @res.push: $str.subst(/\e\[ <[0..9;]>+ m/, '', :g); + } + return @res.join; +} + +sub uncolor (Str $what) is export { + my @res; + my @list = $what.comb(/\d+/); + for @list -> $elem { + if %attrs.reverse.exists($elem) { + @res.push: %attrs.reverse{$elem} + } else { + die("Bad escape sequence: {'\e[' ~ $elem ~ 'm'}") + } + } + return @res.join(' '); +} + +=begin pod + +=head1 NAME + +Term::ANSIColor - Color screen output using ANSI escape sequences + +=head1 SYNOPSIS + + use Term::ANSIColor; + say color('bold'), "this is in bold", color('reset'); + say colored('underline red on_green', 'what a lovely colours!'); + say BOLD, 'good to be fat!', BOLD_OFF; + say 'ok' if colorvalid('magenta', 'on_black', 'inverse'); + say '\e[36m is ', uncolor('\e36m'); + say colorstrip("\e[1mThis is bold\e[0m"); + +=head1 DESCRIPTION + +Term::ANSIColor provides an interface for using colored output +in terminals. The following functions are available: + +=head2 C + +Given a string with color names, the output produced by C +sets the terminal output so the text printed after it will be colored +as specified. The following color names are recognised: + + reset bold underline inverse black red green yellow blue + magenta cyan white default on_black on_red on_green on_yellow + on_blue on_magenta on_cyan on_white on_default + +The on_* family of colors correspond to the background colors. + +=head2 C + +C is similar to C. It takes two Str arguments, +where the first is the colors to be used, and the second is the string +to be colored. The C sequence is automagically placed after +the string. + +=head2 C + +C gets an array of color specifications (like those +passed to C) and returns true if all of them are valid, +false otherwise. + +=head2 C + +C, given a string, removes all the escape sequences +in it, leaving the plain text without effects. + +=head2 C + +Given escape sequences, C returns a string with readable +color names. E.g. passing "\e[36;44m" will result in "cyan on_blue". + +=head1 Constants + +C provides constants which are just strings of +appropriate escape sequences. The following constants are available: + + RESET BOLD UNDERLINE INVERSE BOLD_OFF UNDERLINE_OFF INVERSE_OFF + +=end pod + +# vim: ft=perl6 diff --git a/samples/Perl6/Bailador.pm b/samples/Perl6/Bailador.pm new file mode 100644 index 00000000..96e4d8d1 --- /dev/null +++ b/samples/Perl6/Bailador.pm @@ -0,0 +1,102 @@ +use Bailador::App; +use Bailador::Request; +use Bailador::Response; +use Bailador::Context; +use HTTP::Easy::PSGI; + +module Bailador; + +my $app = Bailador::App.current; + +our sub import { + my $file = callframe(1).file; + my $slash = $file.rindex('/'); + if $slash { + $app.location = $file.substr(0, $file.rindex('/')); + } else { + $app.location = '.'; + } +} + +sub route_to_regex($route) { + $route.split('/').map({ + my $r = $_; + if $_.substr(0, 1) eq ':' { + $r = q{(<-[\/\.]>+)}; + } + $r + }).join("'/'"); +} + +multi parse_route(Str $route) { + my $r = route_to_regex($route); + return "/ ^ $r \$ /".eval; +} + +multi parse_route($route) { + # do nothing + $route +} + +sub get(Pair $x) is export { + my $p = parse_route($x.key) => $x.value; + $app.add_route: 'GET', $p; + return $x; +} + +sub post(Pair $x) is export { + my $p = parse_route($x.key) => $x.value; + $app.add_route: 'POST', $p; + return $x; +} + +sub request is export { $app.context.request } + +sub content_type(Str $type) is export { + $app.response.headers = $type; +} + +sub header(Str $name, Cool $value) is export { + $app.response.headers{$name} = ~$value; +} + +sub status(Int $code) is export { + $app.response.code = $code; +} + +sub template(Str $tmpl, *@params) is export { + $app.template($tmpl, @params); +} + +our sub dispatch_request(Bailador::Request $r) { + return dispatch($r.env); +} + +sub dispatch($env) { + $app.context.env = $env; + + my ($r, $match) = $app.find_route($env); + + if $r { + status 200; + if $match { + $app.response.content = $r.value.(|$match.list); + } else { + $app.response.content = $r.value.(); + } + } + + return $app.response; +} + +sub dispatch-psgi($env) { + return dispatch($env).psgi; +} + +sub baile is export { + given HTTP::Easy::PSGI.new(port => 3000) { + .app(&dispatch-psgi); + say "Entering the development dance floor: http://0.0.0.0:3000"; + .run; + } +} diff --git a/samples/Perl6/ContainsUnicode.pm b/samples/Perl6/ContainsUnicode.pm new file mode 100644 index 00000000..1f3c25c7 --- /dev/null +++ b/samples/Perl6/ContainsUnicode.pm @@ -0,0 +1,7 @@ +module ContainsUnicode { + sub uc-and-join(*@things, :$separator = ', ') is export { + @things».uc.join($separator) + } +} + +# vim: ft=perl6 diff --git a/samples/Perl6/Exception.pm b/samples/Perl6/Exception.pm new file mode 100644 index 00000000..480a8af9 --- /dev/null +++ b/samples/Perl6/Exception.pm @@ -0,0 +1,1431 @@ +my class Failure { ... } +my role X::Comp { ... } +my class X::ControlFlow { ... } + +my class Exception { + has $!ex; + + method backtrace() { Backtrace.new(self) } + + multi method Str(Exception:D:) { + self.?message.Str // 'Something went wrong' + } + + multi method gist(Exception:D:) { + my $str = try self.?message; + return "Error while creating error string: $!" if $!; + $str ~= "\n"; + try $str ~= self.backtrace; + return "$str\nError while creating backtrace: $!.message()\n$!.backtrace.full();" if $!; + return $str; + } + + method throw() is hidden_from_backtrace { + nqp::bindattr(self, Exception, '$!ex', nqp::newexception()) + unless nqp::isconcrete($!ex); + nqp::setpayload($!ex, nqp::decont(self)); + my $msg := self.?message; + nqp::setmessage($!ex, nqp::unbox_s($msg.Str)) + if $msg.defined; + nqp::throw($!ex) + } + method rethrow() is hidden_from_backtrace { + nqp::setpayload($!ex, nqp::decont(self)); + nqp::rethrow($!ex) + } + + method resumable() { + nqp::p6bool(nqp::istrue(nqp::atkey($!ex, 'resume'))); + } + + method resume() { + my Mu $resume := nqp::atkey($!ex, 'resume'); + if $resume { + $resume(); + } + else { + die "Exception is not resumable"; + } + } + + method fail(Exception:D:) { + try self.throw; + my $fail := Failure.new($!); + my Mu $return := nqp::getlexcaller('RETURN'); + $return($fail) unless nqp::isnull($return); + $fail + } + + method is-compile-time { False } +} + +my class X::AdHoc is Exception { + has $.payload; + method message() { $.payload.Str } + method Numeric() { $.payload.Numeric } +} + +my class X::Method::NotFound is Exception { + has $.method; + has $.typename; + has Bool $.private = False; + method message() { + $.private + ?? "No such private method '$.method' for invocant of type '$.typename'" + !! "No such method '$.method' for invocant of type '$.typename'"; + } +} + +my class X::Method::InvalidQualifier is Exception { + has $.method; + has $.invocant; + has $.qualifier-type; + method message() { + "Cannot dispatch to method $.method on {$.qualifier-type.^name} " + ~ "because it is not inherited or done by {$.invocant.^name}"; + } +} + + +sub EXCEPTION(|) { + my Mu $vm_ex := nqp::shift(nqp::p6argvmarray()); + my Mu $payload := nqp::getpayload($vm_ex); + if nqp::p6bool(nqp::istype($payload, Exception)) { + nqp::bindattr($payload, Exception, '$!ex', $vm_ex); + $payload; + } else { + my int $type = nqp::getextype($vm_ex); + my $ex; +#?if parrot + if $type == pir::const::EXCEPTION_METHOD_NOT_FOUND && +#?endif +#?if !parrot + if +#?endif + nqp::p6box_s(nqp::getmessage($vm_ex)) ~~ /"Method '" (.*?) "' not found for invocant of class '" (.+)\'$/ { + + $ex := X::Method::NotFound.new( + method => ~$0, + typename => ~$1, + ); + } + else { + + $ex := nqp::create(X::AdHoc); + nqp::bindattr($ex, X::AdHoc, '$!payload', nqp::p6box_s(nqp::getmessage($vm_ex))); + } + nqp::bindattr($ex, Exception, '$!ex', $vm_ex); + $ex; + } +} + +my class X::Comp::AdHoc { ... } +sub COMP_EXCEPTION(|) { + my Mu $vm_ex := nqp::shift(nqp::p6argvmarray()); + my Mu $payload := nqp::getpayload($vm_ex); + if nqp::p6bool(nqp::istype($payload, Exception)) { + nqp::bindattr($payload, Exception, '$!ex', $vm_ex); + $payload; + } else { + my $ex := nqp::create(X::Comp::AdHoc); + nqp::bindattr($ex, Exception, '$!ex', $vm_ex); + nqp::bindattr($ex, X::AdHoc, '$!payload', nqp::p6box_s(nqp::getmessage($vm_ex))); + $ex; + } +} + + +do { + sub is_runtime($bt) { + for $bt.keys { + try { + my Mu $sub := nqp::getattr(nqp::decont($bt[$_]), ForeignCode, '$!do'); + my Mu $codeobj := nqp::ifnull(nqp::getcodeobj($sub), Mu); + my $is_nqp = $codeobj && $codeobj.HOW.name($codeobj) eq 'NQPRoutine'; + return True if nqp::iseq_s(nqp::getcodename($sub), 'eval') && $is_nqp; + return False if nqp::iseq_s(nqp::getcodename($sub), 'compile') && $is_nqp; + } + } + return False; + } + + + sub print_exception(|) is hidden_from_backtrace { + my Mu $ex := nqp::atpos(nqp::p6argvmarray(), 0); + try { + my $e := EXCEPTION($ex); + my Mu $err := nqp::getstderr(); + +#?if parrot + if $e.is-compile-time || is_runtime($ex.backtrace) { +#?endif +#?if !parrot + if $e.is-compile-time || is_runtime(nqp::backtrace($ex)) { +#?endif + nqp::printfh($err, $e.gist); + nqp::printfh($err, "\n"); + } + else { + nqp::printfh($err, "===SORRY!===\n"); + nqp::printfh($err, $e.Str); + nqp::printfh($err, "\n"); + } + $_() for nqp::hllize(nqp::getcurhllsym('@END_PHASERS')); + } + if $! { +#?if parrot + pir::perl6_based_rethrow__0PP(nqp::getattr(nqp::decont($!), Exception, '$!ex'), $ex); +#?endif +#?if !parrot + nqp::rethrow(nqp::getattr(nqp::decont($!), Exception, '$!ex')); + $ex +#?endif + } + } + + sub print_control(|) is hidden_from_backtrace { + my Mu $ex := nqp::atpos(nqp::p6argvmarray(), 0); + my int $type = nqp::getextype($ex); + if ($type == nqp::const::CONTROL_WARN) { + my Mu $err := nqp::getstderr(); + my $msg = nqp::p6box_s(nqp::getmessage($ex)); + nqp::printfh($err, $msg ?? "$msg" !! "Warning"); +#?if parrot + nqp::printfh($err, Backtrace.new($ex.backtrace, 0).nice(:oneline)); +#?endif +#?if jvm +# XXX Backtraces busted +# nqp::printfh($err, Backtrace.new(nqp::backtrace($ex), 0).nice(:oneline)); +#?endif + nqp::printfh($err, "\n"); +#?if parrot + my $resume := nqp::atkey($ex, 'resume'); + if ($resume) { + $resume(); + } +#?endif +#?if !parrot + nqp::resume($ex) +#?endif + } + if ($type == nqp::const::CONTROL_LAST) { + X::ControlFlow.new(illegal => 'last', enclosing => 'loop construct').throw; + } + if ($type == nqp::const::CONTROL_NEXT) { + X::ControlFlow.new(illegal => 'next', enclosing => 'loop construct').throw; + } + if ($type == nqp::const::CONTROL_REDO) { + X::ControlFlow.new(illegal => 'redo', enclosing => 'loop construct').throw; + } + if ($type == nqp::const::CONTROL_PROCEED) { + X::ControlFlow.new(illegal => 'proceed', enclosing => 'when clause').throw; + } + if ($type == nqp::const::CONTROL_SUCCEED) { + # XXX: should work like leave() ? + X::ControlFlow.new(illegal => 'succeed', enclosing => 'when clause').throw; + } + if ($type == nqp::const::CONTROL_TAKE) { + X::ControlFlow.new(illegal => 'take', enclosing => 'gather').throw; + } + } + + my Mu $comp := nqp::getcomp('perl6'); + $comp.HOW.add_method($comp, 'handle-exception', + method (|) { + my Mu $ex := nqp::atpos(nqp::p6argvmarray(), 1); +#?if parrot + pir::perl6_invoke_catchhandler__vPP(&print_exception, $ex); +#?endif +#?if !parrot + print_exception($ex); +#?endif + nqp::exit(1); + 0; + } + ); + $comp.HOW.add_method($comp, 'handle-control', + method (|) { + my Mu $ex := nqp::atpos(nqp::p6argvmarray(), 1); +#?if parrot + pir::perl6_invoke_catchhandler__vPP(&print_control, $ex); +#?endif +#?if !parrot + print_control($ex); +#?endif + nqp::rethrow($ex); + } + ); + +} + +my role X::OS { + has $.os-error; +} + +my role X::IO does X::OS { }; + +my class X::IO::Rename does X::IO is Exception { + has $.from; + has $.to; + method message() { + "Failed to rename '$.from' to '$.to': $.os-error" + } +} + +my class X::IO::Copy does X::IO is Exception { + has $.from; + has $.to; + method message() { + "Failed to copy '$.from' to '$.to': $.os-error" + } +} + +my class X::IO::Symlink does X::IO is Exception { + has $.target; + has $.name; + method message() { + "Failed to create symlink called '$.name' on target '$.target': $.os-error" + } +} + +my class X::IO::Link does X::IO is Exception { + has $.target; + has $.name; + method message() { + "Failed to create link called '$.name' on target '$.target': $.os-error" + } +} + +my class X::IO::Mkdir does X::IO is Exception { + has $.path; + has $.mode; + method message() { + "Failed to create directory '$.path' with mode '0o{$.mode.fmt("%03o")}': $.os-error" + } +} + +my class X::IO::Chdir does X::IO is Exception { + has $.path; + method message() { + "Failed to change the working directory to '$.path': $.os-error" + } +} + +my class X::IO::Dir does X::IO is Exception { + has $.path; + method message() { + "Failed to get the directory contents of '$.path': $.os-error" + } +} + +my class X::IO::Cwd does X::IO is Exception { + method message() { + "Failed to get the working directory: $.os-error" + } +} + +my class X::IO::Rmdir does X::IO is Exception { + has $.path; + method message() { + "Failed to remove the directory '$.path': $.os-error" + } +} + +my class X::IO::Unlink does X::IO is Exception { + has $.path; + method message() { + "Failed to remove the file '$.path': $.os-error" + } +} + +my class X::IO::Chmod does X::IO is Exception { + has $.path; + has $.mode; + method message() { + "Failed to set the mode of '$.path' to '0o{$.mode.fmt("%03o")}': $.os-error" + } +} + +my role X::Comp is Exception { + has $.filename; + has $.line; + has $.column; + has @.modules; + has $.is-compile-time = False; + has $.pre; + has $.post; + has @.highexpect; + multi method gist(::?CLASS:D: :$sorry = True, :$expect = True) { + if $.is-compile-time { + my $color = %*ENV // $*OS ne 'MSWin32'; + my ($red, $green, $yellow, $clear) = $color + ?? ("\e[31m", "\e[32m", "\e[33m", "\e[0m") + !! ("", "", "", ""); + my $eject = $*OS eq 'MSWin32' ?? "" !! "\x[23CF]"; + my $r = $sorry ?? self.sorry_heading() !! ""; + $r ~= "$.message\nat $.filename():$.line\n------> "; + $r ~= "$green$.pre$yellow$eject$red$.post$clear" if defined $.pre; + if $expect && @.highexpect { + $r ~= "\n expecting any of:"; + for @.highexpect { + $r ~= "\n $_"; + } + } + for @.modules.reverse[1..*] { + $r ~= $_.defined + ?? "\n from module $_ ($_:$_)" + !! "\n from $_:$_"; + } + $r; + } + else { + self.Exception::gist; + } + } + method sorry_heading() { + my $color = %*ENV // $*OS ne 'MSWin32'; + my ($red, $clear) = $color ?? ("\e[31m", "\e[0m") !! ("", ""); + "$red==={$clear}SORRY!$red===$clear Error while compiling $.filename\n" + } + method SET_FILE_LINE($file, $line) { + $!filename = $file; + $!line = $line; + $!is-compile-time = True; + } +} + +my class X::Comp::Group is Exception { + has $.panic; + has @.sorrows; + has @.worries; + + method is-compile-time() { True } + + multi method gist(::?CLASS:D:) { + my $r = ""; + if $.panic || @.sorrows { + my $color = %*ENV // $*OS ne 'MSWin32'; + my ($red, $clear) = $color ?? ("\e[31m", "\e[0m") !! ("", ""); + $r ~= "$red==={$clear}SORRY!$red===$clear\n"; + for @.sorrows { + $r ~= .gist(:!sorry, :!expect) ~ "\n"; + } + if $.panic { + $r ~= $.panic.gist(:!sorry) ~ "\n"; + } + } + if @.worries { + $r ~= $.panic || @.sorrows + ?? "Other potential difficulties:\n" + !! "Potential difficulties:\n"; + for @.worries { + $r ~= .gist(:!sorry, :!expect).indent(4) ~ "\n"; + } + } + $r + } + + method message() { + my @m; + for @.sorrows { + @m.push(.message); + } + if $.panic { + @m.push($.panic.message); + } + for @.worries { + @m.push(.message); + } + @m.join("\n") + } +} + +# XXX a hack for getting line numbers from exceptions from the metamodel +my class X::Comp::AdHoc is X::AdHoc does X::Comp { + method is-compile-time() { True } +} + +my role X::Syntax does X::Comp { } +my role X::Pod { } + +my class X::NYI is Exception { + has $.feature; + method message() { "$.feature not yet implemented. Sorry. " } +} +my class X::Comp::NYI is X::NYI does X::Comp { }; + +my class X::Trait::Unknown is Exception { + has $.type; # is, will, of etc. + has $.subtype; # wrong subtype being tried + has $.declaring; # variable, sub, parameter, etc. + method message () { + "Can't use unknown trait '$.type $.subtype' in a$.declaring declaration." + } +} +my class X::Comp::Trait::Unknown is X::Trait::Unknown does X::Comp { }; + +my class X::Trait::NotOnNative is Exception { + has $.type; # is, will, of etc. + has $.subtype; # wrong subtype being tried + has $.native; # type of native (optional) + method message () { + "Can't use trait '$.type $.subtype' on a native" + ~ ( $.native ?? " $.native." !! "." ); + } +} +my class X::Comp::Trait::NotOnNative is X::Trait::NotOnNative does X::Comp { }; + +my class X::OutOfRange is Exception { + has $.what = 'Argument'; + has $.got = ''; + has $.range = ''; + has $.comment; + method message() { + $.comment.defined + ?? "$.what out of range. Is: $.got, should be in $.range.gist(); $.comment" + !! "$.what out of range. Is: $.got, should be in $.range.gist()" + } +} + +my class X::Buf::AsStr is Exception { + has $.method; + method message() { + "Cannot use a Buf as a string, but you called the $.method method on it"; + } +} +my class X::Buf::Pack is Exception { + has $.directive; + method message() { + "Unrecognized directive '$.directive'"; + } +} + +my class X::Buf::Pack::NonASCII is Exception { + has $.char; + method message() { + "non-ASCII character '$.char' while processing an 'A' template in pack"; + } +} + +my class X::Signature::Placeholder does X::Comp { + has $.placeholder; + method message() { + "Placeholder variable '$.placeholder' cannot override existing signature"; + } +} + +my class X::Placeholder::Block does X::Comp { + has $.placeholder; + method message() { + "Placeholder variable $.placeholder may not be used here because the surrounding block takes no signature"; + } +} + +my class X::Placeholder::Mainline is X::Placeholder::Block { + method message() { + "Cannot use placeholder parameter $.placeholder in the mainline" + } +} + +my class X::Undeclared does X::Comp { + has $.what = 'Variable'; + has $.symbol; + has @.suggestions; + method message() { + my $message := "$.what '$.symbol' is not declared"; + if +@.suggestions == 1 { + $message := "$message. Did you mean '@.suggestions[0]'?"; + } elsif +@.suggestions > 1 { + $message := "$message. Did you mean any of these?\n { @.suggestions.join("\n ") }\n"; + } + $message; + } +} + +my class X::Attribute::Undeclared is X::Undeclared { + has $.package-kind; + has $.package-name; + + method message() { + "Attribute $.symbol not declared in $.package-kind $.package-name"; + } +} + +my class X::Undeclared::Symbols does X::Comp { + has %.post_types; + has %.unk_types; + has %.unk_routines; + has %.routine_suggestion; + has %.type_suggestion; + multi method gist(:$sorry = True) { + ($sorry ?? self.sorry_heading() !! "") ~ self.message + } + method message() { + sub l(@l) { + my @lu = @l.map({ nqp::hllize($_) }).uniq.sort; + 'used at line' ~ (@lu == 1 ?? ' ' !! 's ') ~ @lu.join(', ') + } + sub s(@s) { + "Did you mean '{ @s.join("', '") }'?"; + } + my $r = ""; + if %.post_types { + $r ~= "Illegally post-declared type" ~ (%.post_types.elems == 1 ?? "" !! "s") ~ ":\n"; + for %.post_types.sort(*.key) { + $r ~= " $_.key() &l($_.value)\n"; + } + } + if %.unk_types { + $r ~= "Undeclared name" ~ (%.unk_types.elems == 1 ?? "" !! "s") ~ ":\n"; + for %.unk_types.sort(*.key) { + $r ~= " $_.key() &l($_.value)"; + if +%.type_suggestion{$_.key()} { + $r ~= ". " ~ s(%.type_suggestion{$_.key()}); + } + $r ~= "\n"; + } + } + if %.unk_routines { + $r ~= "Undeclared routine" ~ (%.unk_routines.elems == 1 ?? "" !! "s") ~ ":\n"; + for %.unk_routines.sort(*.key) { + $r ~= " $_.key() &l($_.value)"; + if +%.routine_suggestion{$_.key()} { + $r ~= ". " ~ s(%.routine_suggestion{$_.key()}); + } + $r ~= "\n"; + } + } + $r + } +} + +my class X::Redeclaration does X::Comp { + has $.symbol; + has $.postfix = ''; + has $.what = 'symbol'; + method message() { + "Redeclaration of $.what $.symbol$.postfix"; + } +} + +my class X::Redeclaration::Outer does X::Comp { + has $.symbol; + method message() { + "Lexical symbol '$.symbol' is already bound to an outer symbol;\n" ~ + "the implicit outer binding must be rewritten as OUTER::<$.symbol>\n" ~ + "before you can unambiguously declare a new '$.symbol' in this scope"; + } +} + +my class X::Import::Redeclaration does X::Comp { + has @.symbols; + has $.source-package-name; + method message() { + @.symbols == 1 + ?? "Cannot import symbol @.symbols[0] from $.source-package-name, because it already exists in this lexical scope" + !! ("Cannot import the following symbols from $.source-package-name, because they already exist in this lexical scope: ", @.symbols.join(', ')); + } +} + +my class X::Import::OnlystarProto does X::Comp { + has @.symbols; + has $.source-package-name; + method message() { + @.symbols == 1 + ?? "Cannot import symbol @.symbols[0] from $.source-package-name, only onlystar-protos can be merged" + !! ("Cannot import the following symbols from $.source-package-name, only onlystar-protos can be merged: ", @.symbols.join(', ')); + } +} + +my class X::Phaser::Multiple does X::Comp { + has $.block; + method message() { "Only one $.block block is allowed" } +} + +my class X::Obsolete does X::Comp { + has $.old; + has $.replacement; # can't call it $.new, collides with constructor + has $.when = 'in Perl 6'; + method message() { "Unsupported use of $.old; $.when please use $.replacement" } +} + +my class X::Parameter::Default does X::Comp { + has $.how; + has $.parameter; + method message() { + $.parameter + ?? "Cannot put default on $.how parameter $.parameter" + !! "Cannot put default on anonymous $.how parameter"; + } +} + +my class X::Parameter::Placeholder does X::Comp { + has $.parameter; + has $.right; + method message() { + "In signature parameter, placeholder variables like $.parameter are illegal\n" + ~ "you probably meant a named parameter: '$.right'"; + } +} + +my class X::Parameter::Twigil does X::Comp { + has $.parameter; + has $.twigil; + method message() { + "In signature parameter $.parameter, it is illegal to use the $.twigil twigil"; + } +} + +my class X::Parameter::MultipleTypeConstraints does X::Comp { + has $.parameter; + method message() { + ($.parameter ?? "Parameter $.parameter" !! 'A parameter') + ~ " may only have one prefix type constraint"; + } +} + +my class X::Parameter::WrongOrder does X::Comp { + has $.misplaced; + has $.parameter; + has $.after; + method message() { + "Cannot put $.misplaced parameter $.parameter after $.after parameters"; + } +} + +my class X::Parameter::InvalidType does X::Comp { + has $.typename; + has @.suggestions; + method message() { + my $msg := "Invalid typename '$.typename' in parameter declaration."; + if +@.suggestions > 0 { + $msg := $msg ~ " Did you mean '" ~ @.suggestions.join("', '") ~ "'?"; + } + return $msg; + } +} + +my class X::Signature::NameClash does X::Comp { + has $.name; + method message() { + "Name $.name used for more than one named parameter"; + } +} + +my class X::Method::Private::Permission does X::Comp { + has $.method; + has $.source-package; + has $.calling-package; + method message() { + "Cannot call private method '$.method' on package $.source-package because it does not trust $.calling-package"; + } +} + +my class X::Method::Private::Unqualified does X::Comp { + has $.method; + method message() { + "Private method call to $.method must be fully qualified with the package containing the method"; + } +} + +my class X::Bind is Exception { + has $.target; + method message() { + $.target.defined + ?? "Cannot bind to $.target" + !! 'Cannot use bind operator with this left-hand side' + } +} +my class X::Bind::NativeType does X::Comp { + has $.name; + method message() { + "Cannot bind to natively typed variable '$.name'; use assignment instead" + } +} +my class X::Bind::Slice is Exception { + has $.type; + method message() { + "Cannot bind to {$.type.^name} slice"; + } +} +my class X::Bind::ZenSlice is X::Bind::Slice { + method message() { + "Cannot bind to {$.type.^name} zen slice"; + } +} + +my class X::Value::Dynamic does X::Comp { + has $.what; + method message() { "$.what value must be known at compile time" } +} + +my class X::Syntax::Name::Null does X::Syntax { + method message() { 'Name component may not be null'; } +} + +my class X::Syntax::UnlessElse does X::Syntax { + method message() { '"unless" does not take "else", please rewrite using "if"' } +} + +my class X::Syntax::KeywordAsFunction does X::Syntax { + has $.word; + has $.needparens; + method message { + "Word '$.word' interpreted as '{$.word}()' function call; please use whitespace " + ~ ($.needparens ?? 'around the parens' !! 'instead of parens') + } +} + +my class X::Syntax::Malformed::Elsif does X::Syntax { + has $.what = 'else if'; + method message() { qq{In Perl 6, please use "elsif' instead of "$.what"} } +} + +my class X::Syntax::Reserved does X::Syntax { + has $.reserved; + has $.instead = ''; + method message() { "The $.reserved is reserved$.instead" } +} + +my class X::Syntax::P5 does X::Syntax { + method message() { 'This appears to be Perl 5 code' } +} + +my class X::Syntax::NegatedPair does X::Syntax { + has $.key; + method message() { "Argument not allowed on negated pair with key '$.key'" } +} + +my class X::Syntax::Variable::Numeric does X::Syntax { + has $.what = 'variable'; + method message() { "Cannot declare a numeric $.what" } +} + +my class X::Syntax::Variable::Match does X::Syntax { + method message() { 'Cannot declare a match variable' } +} + +my class X::Syntax::Variable::Twigil does X::Syntax { + has $.twigil; + has $.scope; + method message() { "Cannot use $.twigil twigil on $.scope variable" } +} + +my class X::Syntax::Variable::IndirectDeclaration does X::Syntax { + method message() { 'Cannot declare a variable by indirect name (use a hash instead?)' } +} + +my class X::Syntax::Augment::WithoutMonkeyTyping does X::Syntax { + method message() { "augment not allowed without 'use MONKEY_TYPING'" }; +} + +my class X::Syntax::Augment::Illegal does X::Syntax { + has $.package; + method message() { "Cannot augment $.package because it is closed" }; +} + +my class X::Syntax::Argument::MOPMacro does X::Syntax { + has $.macro; + method message() { "Cannot give arguments to $.macro" }; +} + +my class X::Does::TypeObject is Exception { + method message() { "Cannot use 'does' operator with a type object." } +} + +my class X::Role::Initialization is Exception { + has $.role; + method message() { "Can only supply an initialization value for a role if it has a single public attribute, but this is not the case for '{$.role.^name}'" } +} + +my class X::Syntax::Comment::Embedded does X::Syntax { + method message() { "Opening bracket required for #` comment" } +} + +my class X::Syntax::Pod::BeginWithoutIdentifier does X::Syntax does X::Pod { + method message() { + '=begin must be followed by an identifier; (did you mean "=begin pod"?)' + } +} + +my class X::Syntax::Pod::BeginWithoutEnd does X::Syntax does X::Pod { + method message() { '=begin without matching =end' } +} + +my class X::Syntax::Confused does X::Syntax { + has $.reason = 'unknown'; + method message() { $.reason eq 'unknown' ?? 'Confused' !! $.reason } +} + +my class X::Syntax::Malformed does X::Syntax { + has $.what; + method message() { "Malformed $.what" } +} +my class X::Syntax::Missing does X::Syntax { + has $.what; + method message() { "Missing $.what" } +} + +my class X::Syntax::Perl5Var does X::Syntax { + has $.name; + my %m = + '$*' => '^^ and $$', + '$"' => '.join() method', + '$$' => '$*PID', + '$(' => '$*GID', + '$)' => '$*EGID', + '$<' => '$*UID', + '$>' => '$*EUID', + '$;' => 'real multidimensional hashes', + '$&' => '$<>', + '$`' => 'explicit pattern before <(', + '$\'' => 'explicit pattern after )>', + '$,' => '$*OUT.output_field_separator()', + '$.' => "the filehandle's .line method", + '$\\' => "the filehandle's .ors attribute", + '$|' => ':autoflush on open', + '$?' => '$! for handling child errors also', + '$@' => '$!', + '$#' => '.fmt', + '$[' => 'user-defined array indices', + '$]' => '$*PERL_VERSION', + + '$^C' => 'COMPILING namespace', + '$^D' => '$*DEBUGGING', + '$^E' => '$!.extended_os_error', + '$^F' => '$*SYSTEM_FD_MAX', + '$^H' => '$?FOO variables', + '$^I' => '$*INPLACE', + '$^M' => 'a global form such as $*M', + '$^N' => '$/[*-1]', + '$^O' => '$?OS or $*OS', + '$^R' => 'an explicit result variable', + '$^S' => 'context function', + '$^T' => '$*BASETIME', + '$^V' => '$*PERL_VERSION', + '$^W' => '$*WARNING', + '$^X' => '$*EXECUTABLE_NAME', + + '$:' => 'Form module', + '$-' => 'Form module', + '$+' => 'Form module', + '$=' => 'Form module', + '$%' => 'Form module', + '$^' => 'Form module', + '$~' => 'Form module', + '$^A' => 'Form module', + '$^L' => 'Form module', + + '@-' => '.from method', + '@+' => '.to method', + + '%-' => '.from method', + '%+' => '.to method', + '%^H' => '$?FOO variables', + ; + method message() { + my $v = $.name ~~ m/ <[ $ @ % & ]> [ \^ <[ A..Z ]> | \W ] /; + $v + ?? %m{~$v} + ?? "Unsupported use of $v variable; in Perl 6 please use {%m{~$v}}" + !! "Unsupported use of $v variable" + !! 'Non-declarative sigil is missing its name'; + } +} + +my class X::Syntax::Self::WithoutObject does X::Syntax { + method message() { "'self' used where no object is available" } +} +my class X::Syntax::VirtualCall does X::Syntax { + has $.call; + method message() { "Virtual call $.call may not be used on partially constructed objects" } +} +my class X::Syntax::NoSelf does X::Syntax { + has $.variable; + method message() { "Variable $.variable used where no 'self' is available" } +} + +my class X::Syntax::Number::RadixOutOfRange does X::Syntax { + has $.radix; + method message() { "Radix $.radix out of range (allowed: 2..36)" } +} + +my class X::Syntax::NonAssociative does X::Syntax { + has $.left; + has $.right; + method message() { + "Operators '$.left' and '$.right' are non-associative and require parenthesis"; + } +} + +my class X::Syntax::Regex::Adverb does X::Syntax { + has $.adverb; + has $.construct; + method message() { "Adverb $.adverb not allowed on $.construct" } +} + +my class X::Syntax::Regex::UnrecognizedMetachar does X::Syntax { + has $.metachar; + method message() { "Unrecognized regex metacharacter $.metachar (must be quoted to match literally)" } +} + +my class X::Syntax::Regex::NullRegex does X::Syntax { + method message() { 'Null regex not allowed' } +} + +my class X::Syntax::Signature::InvocantMarker does X::Syntax { + method message() { + "Can only use : as invocant marker in a signature after the first parameter" + } +} + +my class X::Syntax::Extension::Category does X::Syntax { + has $.category; + method message() { + "Cannot add tokens of category '$.category'"; + } +} + +my class X::Syntax::Extension::Null does X::Syntax { + method message() { + "Null operator is not allowed"; + } +} + +my class X::Syntax::InfixInTermPosition does X::Syntax { + has $.infix; + method message() { + "Preceding context expects a term, but found infix $.infix instead"; + } +} + +my class X::Attribute::Package does X::Comp { + has $.package-kind; + has $.name; + method message() { "A $.package-kind cannot have attributes, but you tried to declare '$.name'" } +} +my class X::Attribute::NoPackage does X::Comp { + has $.name; + method message() { "You cannot declare attribute '$.name' here; maybe you'd like a class or a role?" } +} +my class X::Declaration::Scope does X::Comp { + has $.scope; + has $.declaration; + method message() { "Cannot use '$.scope' with $.declaration declaration" } +} + +my class X::Declaration::Scope::Multi is X::Declaration::Scope { + method message() { + "Cannot use '$.scope' with individual multi candidates. Please declare an {$.scope}-scoped proto instead"; + } +} + +my class X::Anon::Multi does X::Comp { + has $.multiness; + has $.routine-type = 'routine'; + method message() { "Cannot put $.multiness on anonymous $.routine-type" } +} +my class X::Anon::Augment does X::Comp { + has $.package-kind; + method message() { "Cannot augment anonymous $.package-kind" } +} +my class X::Augment::NoSuchType does X::Comp { + has $.package-kind; + has $.package; + method message() { "You tried to augment $.package-kind $.package, but it does not exist" } +} + +my class X::Routine::Unwrap is Exception { + method message() { "Cannot unwrap routine: invalid wrap handle" } +} + +my class X::Constructor::Positional is Exception { + has $.type; + method message() { "Default constructor for '" ~ $.type.^name ~ "' only takes named arguments" } +} + +my class X::Hash::Store::OddNumber is Exception { + method message() { "Odd number of elements found where hash expected" } +} + +my class X::Package::Stubbed does X::Comp { + has @.packages; + # TODO: suppress display of line number + method message() { + "The following packages were stubbed but not defined:\n " + ~ @.packages.join("\n "); + } +} + +my class X::Phaser::PrePost is Exception { + has $.phaser = 'PRE'; + has $.condition; + method message { + my $what = $.phaser eq 'PRE' ?? 'Precondition' !! 'Postcondition'; + $.condition.defined + ?? "$what '$.condition.trim()' failed" + !! "$what failed"; + } +} + +my class X::Str::Numeric is Exception { + has $.source; + has $.pos; + has $.reason; + method source-indicator { + constant marker = chr(0x23CF); + join '', "in '", + $.source.substr(0, $.pos), + marker, + $.source.substr($.pos), + "' (indicated by ", + marker, + ")", + ; + } + method message() { + "Cannot convert string to number: $.reason $.source-indicator"; + } +} + +my class X::Str::Match::x is Exception { + has $.got; + method message() { + "in Str.match, got invalid value of type {$.got.^name} for :x, must be Int or Range" + } +} + +my class X::Str::Trans::IllegalKey is Exception { + has $.key; + method message { + "in Str.trans, got illegal substitution key of type {$.key.^name} (should be a Regex or Str)" + } +} +my class X::Str::Trans::InvalidArg is Exception { + has $.got; + method message() { + "Only Pair objects are allowed as arguments to Str.trans, got {$.got.^name}"; + } +} + +my class X::Range::InvalidArg is Exception { + has $.got; + method message() { + "{$.got.^name} objects are not valid endpoints for Ranges"; + } +} + +my class X::Sequence::Deduction is Exception { + method message() { 'Unable to deduce sequence' } +} + +my class X::Backslash::UnrecognizedSequence does X::Syntax { + has $.sequence; + method message() { "Unrecognized backslash sequence: '\\$.sequence'" } +} + +my class X::Backslash::NonVariableDollar does X::Syntax { + method message() { "Non-variable \$ must be backslashed" } +} + +my class X::ControlFlow is Exception { + has $.illegal; # something like 'next' + has $.enclosing; # .... outside a loop + + method message() { "$.illegal without $.enclosing" } +} +my class X::ControlFlow::Return is X::ControlFlow { + method illegal() { 'return' } + method enclosing() { 'Routine' } + method message() { 'Attempt to return outside of any Routine' } +} + +my class X::Composition::NotComposable does X::Comp { + has $.target-name; + has $.composer; + method message() { + $.composer.^name ~ " is not composable, so $.target-name cannot compose it"; + } +} + +my class X::TypeCheck is Exception { + has $.operation; + has $.got; + has $.expected; + method message() { + "Type check failed in $.operation; expected '{$.expected.^name}' but got '{$.got.^name}'"; + + } +} + +my class X::TypeCheck::Binding is X::TypeCheck { + method operation { 'binding' } +} +my class X::TypeCheck::Return is X::TypeCheck { + method operation { 'returning' } + method message() { + "Type check failed for return value; expected '{$.expected.^name}' but got '{$.got.^name}'"; + } +} +my class X::TypeCheck::Assignment is X::TypeCheck { + has $.symbol; + method operation { 'assignment' } + method message { + $.symbol.defined + ?? "Type check failed in assignment to '$.symbol'; expected '{$.expected.^name}' but got '{$.got.^name}'" + !! "Type check failed in assignment; expected '{$.expected.^name}' but got '{$.got.^name}'"; + } +} +my class X::TypeCheck::Argument is X::TypeCheck { + has $.protoguilt; + has @.arguments; + has $.objname; + has $.signature; + method message { + ($.protoguilt ?? "Calling proto of '" !! "Calling '") ~ + $.objname ~ "' " ~ + (+@.arguments == 0 + ?? "requires arguments\n" + !! "will never work with argument types (" ~ join(', ', @.arguments) ~ ")\n") + ~ $.signature + } +} + +my class X::TypeCheck::Splice is X::TypeCheck does X::Comp { + has $.action; + method message { + "Type check failed in {$.action}; expected {$.expected.^name} but got {$.got.^name}"; + } + +} + +my class X::Assignment::RO is Exception { + method message { + "Cannot modify an immutable value"; + } +} + +my class X::Immutable is Exception { + has $.typename; + has $.method; + method message { + "Cannot call '$.method' on an immutable '$.typename'"; + } +} + +my class X::NoDispatcher is Exception { + has $.redispatcher; + method message() { + "$.redispatcher is not in the dynamic scope of a dispatcher"; + } +} + +my class X::Localizer::NoContainer is Exception { + has $.localizer; + method message() { + "Can only use '$.localizer' on a container"; + } +} + +my class X::Mixin::NotComposable is Exception { + has $.target; + has $.rolish; + method message() { + "Cannot mix in non-composable type {$.rolish.^name} into object of type {$.target.^name}"; + } +} + +my class X::Inheritance::Unsupported does X::Comp { + # note that this exception is thrown before the child type object + # has been composed, so it's useless to carry it around. Use the + # name instead. + has $.child-typename; + has $.parent; + method message { + $.parent.^name ~ ' does not support inheritance, so ' + ~ $.child-typename ~ ' cannot inherit from it'; + } +} + +my class X::Inheritance::UnknownParent is Exception { + has $.child; + has $.parent; + has @.suggestions is rw; + + method message { + my $message := "'" ~ $.child ~ "' cannot inherit from '" ~ $.parent ~ "' because it is unknown."; + if +@.suggestions > 1 { + $message := $message ~ "\nDid you mean one of these?\n '" ~ @.suggestions.join("'\n '") ~ "'\n"; + } elsif +@.suggestions == 1 { + $message := $message ~ "\nDid you mean '" ~ @.suggestions[0] ~ "'?\n"; + } + return $message; + } +} + +my class X::Inheritance::SelfInherit is Exception { + has $.name; + + method message { + "'$.name' cannot inherit from itself." + } +} + +my class X::Export::NameClash does X::Comp { + has $.symbol; + method message() { + "A symbol '$.symbol' has already been exported"; + } +} + +my class X::HyperOp::NonDWIM is Exception { + has &.operator; + has $.left-elems; + has $.right-elems; + method message() { + "Lists on both side of non-dwimmy hyperop of &.operator.name() are not of the same length\n" + ~ "left: $.left-elems elements, right: $.right-elems elements"; + } +} + +my class X::Set::Coerce is Exception { + has $.thing; + method message { + "Cannot coerce object of type {$.thing.^name} to Set. To create a one-element set, pass it to the 'set' function"; + } +} + + +my role X::Temporal is Exception { } +my class X::Temporal::InvalidFormat does X::Temporal { + has $.invalid-str; + has $.target = 'Date'; + has $.format; + method message() { + "Invalid $.target string '$.invalid-str'; use $.format instead"; + } +} +my class X::DateTime::TimezoneClash does X::Temporal { + method message() { + 'DateTime.new(Str): :timezone argument not allowed with a timestamp offset'; + } +} +my class X::DateTime::InvalidDeltaUnit does X::Temporal { + has $.unit; + method message() { + "Cannnot use unit $.unit with Date.delta"; + } +} + +my class X::Eval::NoSuchLang is Exception { + has $.lang; + method message() { + "No compiler available for language '$.lang'"; + } +} + +my class X::Import::MissingSymbols is Exception { + has $.from; + has @.missing; + method message() { + "Trying to import from '$.from', but the following symbols are missing: " + ~ @.missing.join(', '); + } +} + +my class X::Numeric::Real is Exception { + has $.target; + has $.reason; + has $.source; + + method message() { + "Can not convert $.source to {$.target.^name}: $.reason"; + } +} + +my class X::Numeric::DivideByZero is Exception { + has $.using; + method message() { + "Divide by zero" ~ ( $.using ?? " using $.using" !! '' ); + } +} + +my class X::PseudoPackage::InDeclaration does X::Comp { + has $.pseudo-package; + has $.action; + method message() { + "Cannot use pseudo package $.pseudo-package in $.action"; + } +} + +my class X::NoSuchSymbol is Exception { + has $.symbol; + method message { "No such symbol '$.symbol'" } +} + +my class X::Item is Exception { + has $.aggregate; + has $.index; + method message { "Cannot index {$.aggregate.^name} with $.index" } +} + +my class X::Multi::Ambiguous is Exception { + has $.dispatcher; + has @.ambiguous; + method message { + join "\n", + "Ambiguous call to '$.dispatcher.name()'; these signatures all match:", + @.ambiguous.map(*.signature.perl) + } +} + +my class X::Multi::NoMatch is Exception { + has $.dispatcher; + method message { + join "\n", + "Cannot call '$.dispatcher.name()'; none of these signatures match:", + $.dispatcher.dispatchees.map(*.signature.perl) + } +} + +my class X::Caller::NotDynamic is Exception { + has $.symbol; + method message() { + "Cannot access '$.symbol' through CALLER, because it is not declared as dynamic"; + } +} + +{ + my %c_ex; + %c_ex{'X::TypeCheck::Binding'} := sub ($got, $expected) is hidden_from_backtrace { + X::TypeCheck::Binding.new(:$got, :$expected).throw; + }; + %c_ex := sub ($symbol, $got, $expected) is hidden_from_backtrace { + X::TypeCheck::Assignment.new(:$symbol, :$got, :$expected).throw; + }; + %c_ex{'X::TypeCheck::Return'} := sub ($got, $expected) is hidden_from_backtrace { + X::TypeCheck::Return.new(:$got, :$expected).throw; + }; + %c_ex := sub () is hidden_from_backtrace { + X::Assignment::RO.new.throw; + }; + %c_ex{'X::ControlFlow::Return'} := sub () is hidden_from_backtrace { + X::ControlFlow::Return.new().throw; + }; + %c_ex{'X::NoDispatcher'} := sub ($redispatcher) is hidden_from_backtrace { + X::NoDispatcher.new(:$redispatcher).throw; + }; + %c_ex{'X::Multi::Ambiguous'} := sub ($dispatcher, @ambiguous) is hidden_from_backtrace { + X::Multi::Ambiguous.new(:$dispatcher, :@ambiguous).throw + }; + %c_ex{'X::Multi::NoMatch'} := sub ($dispatcher) is hidden_from_backtrace { + X::Multi::NoMatch.new(:$dispatcher).throw + }; + my Mu $parrot_c_ex := nqp::getattr(%c_ex, EnumMap, '$!storage'); + nqp::bindcurhllsym('P6EX', $parrot_c_ex); + + 0; +} + + +# vim: ft=perl6 diff --git a/samples/Perl6/Model.pm b/samples/Perl6/Model.pm new file mode 100644 index 00000000..1c2bea9d --- /dev/null +++ b/samples/Perl6/Model.pm @@ -0,0 +1,146 @@ +use v6; + +class Math::Model; + +use Math::RungeKutta; +# TODO: only load when needed +use SVG; +use SVG::Plot; + +has %.derivatives; +has %.variables; +has %.initials; +has @.captures is rw; + +has %!inv = %!derivatives.invert; +# in Math::Model all variables are accessible by name +# in contrast Math::RungeKutta uses vectors, so we need +# to define an (arbitrary) ordering +# @!deriv-names holds the names of the derivatives in a fixed +# order, sod @!deriv-names[$number] turns the number into a name +# %!deriv-keying{$name} translates a name into the corresponding index +has @!deriv-names = %!inv.keys; +has %!deriv-keying = @!deriv-names Z=> 0..Inf; + +# snapshot of all variables in the current model +has %!current-values; + +has %.results; +has @.time; + +has $.numeric-error is rw = 0.0001; + +my sub param-names(&c) { + &c.signature.params».name».substr(1).grep({ $_ ne '_'}); +} + +method !params-for(&c) { + param-names(&c).map( {; $_ => %!current-values{$_} } ).hash; +} + +method topo-sort(*@vars) { + my %seen; + my @order; + sub topo(*@a) { + for @a { + next if %!inv.exists($_) || %seen{$_} || $_ eq 'time'; + die "Undeclared variable '$_' used in model" + unless %.variables.exists($_); + topo(param-names(%.variables{$_})); + @order.push: $_; + %seen{$_}++; + } + } + topo(@vars); +# say @order.perl; + @order; +} + + +method integrate(:$from = 0, :$to = 10, :$min-resolution = ($to - $from) / 20, :$verbose) { + for %.derivatives -> $d { + die "There must be a variable defined for each derivative, missing for '$d.key()'" + unless %.variables.exists($d.key) || %!inv.exists($d.key); + die "There must be an initial value defined for each derivative target, missing for '$d.value()'" + unless %.initials.exists($d.value); + } + + %!current-values = %.initials; + %!current-values