diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | doc/docs/lexerdevelopment.rst | 2 | ||||
-rw-r--r-- | doc/faq.rst | 2 | ||||
-rw-r--r-- | pygments/lexers/_mapping.py | 1 | ||||
-rw-r--r-- | pygments/lexers/compiled.py | 69 | ||||
-rw-r--r-- | pygments/lexers/functional.py | 137 | ||||
-rw-r--r-- | pygments/lexers/jvm.py | 1 | ||||
-rw-r--r-- | pygments/lexers/other.py | 2 | ||||
-rw-r--r-- | pygments/lexers/sql.py | 7 | ||||
-rw-r--r-- | tests/examplefiles/99_bottles_of_beer.chpl | 43 | ||||
-rw-r--r-- | tests/examplefiles/all.nit | 1986 | ||||
-rw-r--r-- | tests/examplefiles/example.golo | 113 | ||||
-rw-r--r-- | tests/examplefiles/example_elixir.ex | 48 | ||||
-rw-r--r-- | tests/examplefiles/rust_example.rs | 2 | ||||
-rw-r--r-- | tests/examplefiles/test.idr | 8 |
16 files changed, 2337 insertions, 90 deletions
@@ -14,6 +14,7 @@ Other contributors, listed alphabetically, are: * Jeffrey Arnold -- R/S, Rd, BUGS, Jags, and Stan lexers * Jeremy Ashkenas -- CoffeeScript lexer * Stefan Matthias Aust -- Smalltalk lexer +* Lucas Bajolet -- Nit lexer * Ben Bangert -- Mako lexers * Max Battcher -- Darcs patch lexer * Thomas Baruchel -- APL lexer @@ -41,6 +41,7 @@ Version 2.0 * Inform 6/7 (PR#281) * MQL (PR#285) * APL (#969) + * Nit (PR#375) - New styles: "xcode" and "igor", similar to the default highlighting of the respective IDEs. @@ -105,7 +106,9 @@ Version 2.0 - C family lexers: fix parsing of indented preprocessor directives (#944). -- Rust lexer: update to 0.9 language version (PR#270). +- Rust lexer: update to 0.9 language version (PR#270, PR#388). + +- Elixir lexer: update to 0.15 language version (PR#392). Version 1.6 diff --git a/doc/docs/lexerdevelopment.rst b/doc/docs/lexerdevelopment.rst index eab1306a..23f7cdc6 100644 --- a/doc/docs/lexerdevelopment.rst +++ b/doc/docs/lexerdevelopment.rst @@ -190,7 +190,7 @@ nevertheless need a group, use a non-capturing group defined using this syntax: If you find yourself needing a capturing group inside the regex which shouldn't be part of the output but is used in the regular expressions for backreferencing (eg: ``r'(<(foo|bar)>)(.*?)(</\2>)'``), you can pass `None` -to the bygroups function and it will skip that group will be skipped in the +to the bygroups function and that group will be skipped in the output. diff --git a/doc/faq.rst b/doc/faq.rst index 0f65b9fe..f040e053 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -58,7 +58,7 @@ Usage as a library is thoroughly demonstrated in the Documentation section. How do I make a new style? -------------------------- -Please see the documentation on styles. +Please see the :doc:`documentation on styles <docs/styles>`. How can I report a bug or suggest a feature? -------------------------------------------- diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py index b028aee6..d505dcf5 100644 --- a/pygments/lexers/_mapping.py +++ b/pygments/lexers/_mapping.py @@ -239,6 +239,7 @@ LEXERS = { 'NewspeakLexer': ('pygments.lexers.other', 'Newspeak', ('newspeak',), ('*.ns2',), ('text/x-newspeak',)), 'NginxConfLexer': ('pygments.lexers.text', 'Nginx configuration file', ('nginx',), (), ('text/x-nginx-conf',)), 'NimrodLexer': ('pygments.lexers.compiled', 'Nimrod', ('nimrod', 'nim'), ('*.nim', '*.nimrod'), ('text/x-nimrod',)), + 'NitLexer': ('pygments.lexers.compiled', 'Nit', ('nit',), ('*.nit',), ()), 'NixLexer': ('pygments.lexers.functional', 'Nix', ('nixos', 'nix'), ('*.nix',), ('text/x-nix',)), 'NumPyLexer': ('pygments.lexers.math', 'NumPy', ('numpy',), (), ()), 'ObjdumpLexer': ('pygments.lexers.asm', 'objdump', ('objdump',), ('*.objdump',), ('text/x-objdump',)), diff --git a/pygments/lexers/compiled.py b/pygments/lexers/compiled.py index 38bd901f..6556b77e 100644 --- a/pygments/lexers/compiled.py +++ b/pygments/lexers/compiled.py @@ -32,7 +32,7 @@ __all__ = ['CLexer', 'CppLexer', 'DLexer', 'DelphiLexer', 'ECLexer', 'DylanLidLexer', 'DylanConsoleLexer', 'CobolLexer', 'CobolFreeformatLexer', 'LogosLexer', 'ClayLexer', 'PikeLexer', 'ChapelLexer', 'EiffelLexer', 'Inform6Lexer', 'Inform7Lexer', - 'Inform6TemplateLexer', 'MqlLexer', 'SwiftLexer'] + 'Inform6TemplateLexer', 'MqlLexer', 'SwiftLexer', 'NitLexer'] class CFamilyLexer(RegexLexer): @@ -3321,7 +3321,7 @@ class RustLexer(RegexLexer): (r'\s+', Text), (r'//[/!](.*?)\n', Comment.Doc), (r'//(.*?)\n', Comment.Single), - (r'/[*](.|\n)*?[*]/', Comment.Multiline), + (r'/\*', Comment.Multiline, 'comment'), # Keywords (r'(as|box|break|continue' @@ -3403,6 +3403,12 @@ class RustLexer(RegexLexer): (r'([A-Za-z_]\w*)!\s*([A-Za-z_]\w*)?\(', bygroups(Comment.Preproc, Name), 'macro('), ], + 'comment': [ + (r'[^*/]+', Comment.Multiline), + (r'/\*', Comment.Multiline, '#push'), + (r'\*/', Comment.Multiline, '#pop'), + (r'[*/]', Comment.Multiline), + ], 'number_lit': [ (r'(([ui](8|16|32|64)?)|(f(32|64)?))?', Keyword, '#pop'), ], @@ -3920,11 +3926,11 @@ class ChapelLexer(RegexLexer): (r'(false|nil|true)\b', Keyword.Constant), (r'(bool|complex|imag|int|opaque|range|real|string|uint)\b', Keyword.Type), - (r'(atomic|begin|break|by|cobegin|coforall|continue|iter|' + (r'(align|atomic|begin|break|by|cobegin|coforall|continue|' r'delete|dmapped|do|domain|else|enum|export|extern|for|forall|' - r'if|index|inline|label|lambda|let|local|new|on|otherwise|' - r'reduce|return|scan|select|serial|single|sparse|' - r'subdomain|sync|then|use|when|where|while|yield|zip)\b', + r'if|index|inline|iter|label|lambda|let|local|new|noinit|on|' + r'otherwise|pragma|reduce|return|scan|select|serial|single|sparse|' + r'subdomain|sync|then|use|when|where|while|with|yield|zip)\b', Keyword), (r'(proc)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'procname'), (r'(class|module|record|union)(\s+)', bygroups(Keyword, Text), @@ -3946,15 +3952,17 @@ class ChapelLexer(RegexLexer): (r'0[bB][0-1]+', Number.Bin), # -- hex (r'0[xX][0-9a-fA-F]+', Number.Hex), + # -- octal + (r'0[oO][0-7]+', Number.Oct), # -- decimal - (r'(0|[1-9][0-9]*)', Number.Integer), + (r'[0-9]+', Number.Integer), # strings (r'["\'](\\\\|\\"|[^"\'])*["\']', String), # tokens (r'(=|\+=|-=|\*=|/=|\*\*=|%=|&=|\|=|\^=|&&=|\|\|=|<<=|>>=|' - r'<=>|\.\.|by|#|\.\.\.|' + r'<=>|<~>|\.\.|by|#|\.\.\.|' r'&&|\|\||!|&|\||\^|~|<<|>>|' r'==|!=|<=|>=|<|>|' r'[+\-*/%]|\*\*)', Operator), @@ -5190,3 +5198,48 @@ class SwiftLexer(ObjectiveCLexer): elif value in self.operators: token = Operator yield index, token, value + + +class NitLexer(RegexLexer): + """ + For `nit <http://nitlanguage.org>`_ source. + + .. versionadded:: 2.0 + """ + + name = 'Nit' + aliases = ['nit'] + filenames = ['*.nit'] + tokens = { + 'root': [ + (r'#.*?$', Comment.Single), + (r'(package|module|import|class|abstract|interface|' + 'universal|enum|end|fun|type|init|redef|isa|do|' + 'readable|writable|var|intern|extern|public|protected|' + 'private|intrude|if|then|else|while|loop|for|in|and|' + 'or|not|implies|return|continue|break|abort|assert|' + 'new|is|once|super|self|true|false|nullable|null|as|' + 'isset|label|__debug__)(?=( |\n|\t|\r|\())', Keyword), + (r'[A-Z][A-Za-z0-9_]*', Name.Class), + (r'"""(([^\'\\]|\\.)|\\r|\\n)*(({{?)?(""?{{?)*""""*)', String), #Simple long string + (r'\'\'\'(((\\.|[^\'\\])|\\r|\\n)|\'((\\.|[^\'\\])|\\r|\\n)|' + r'\'\'((\\.|[^\'\\])|\\r|\\n))*\'\'\'', String), #Simple long string alt + (r'"""(([^\'\\]|\\.)|\\r|\\n)*((""?)?({{?""?)*{{{{*)', String), #Start long string + (r'}}}(((\\.|[^\'\\])|\\r|\\n))*(""?)?({{?""?)*{{{{*', String), #Mid long string + (r'}}}(((\\.|[^\'\\])|\\r|\\n))*({{?)?(""?{{?)*""""*', String), #End long string + (r'"(\\.|([^"}{\\]))*"', String), #Simple String + (r'"(\\.|([^"}{\\]))*{', String), #Start string + (r'}(\\.|([^"}{\\]))*{', String), #Mid String + (r'}(\\.|([^"}{\\]))*"', String), #End String + (r'(\'[^\'\\]\')|(\'\\.\')', String.Char), + (r'[0-9]+', Number.Integer), + (r'[0-9]*.[0-9]+', Number.Float), + (r'0(x|X)[0-9A-Fa-f]+', Number.Hex), + (r'[a-z][A-Za-z0-9_]*', Name), + (r'_[A-Za-z0-9_]+', Name.Variable.Instance), + (r'==|!=|<==>|>=|>>|>|<=|<<|<|\+|-|=|/|\*|%|\+=|-=|!|@', Operator), + (r'\(|\)|\[|\]|,|\.\.\.|\.\.|\.|::|:', Punctuation), + (r'`{[^`]*`}', Text), # Extern blocks won't be Lexed by Nit + ('(\r|\n| |\t)+', Text)] + } + diff --git a/pygments/lexers/functional.py b/pygments/lexers/functional.py index a22c4f55..01ba03c6 100644 --- a/pygments/lexers/functional.py +++ b/pygments/lexers/functional.py @@ -1530,26 +1530,27 @@ class IdrisLexer(RegexLexer): 'let','proof','of','then','static','where','_','with', 'pattern', 'term', 'syntax','prefix', 'postulate','parameters','record','dsl','impossible','implicit', - 'tactics','intros','intro','compute','refine','exaxt','trivial'] + 'tactics','intros','intro','compute','refine','exact','trivial'] ascii = ['NUL','SOH','[SE]TX','EOT','ENQ','ACK', 'BEL','BS','HT','LF','VT','FF','CR','S[OI]','DLE', 'DC[1-4]','NAK','SYN','ETB','CAN', 'EM','SUB','ESC','[FGRU]S','SP','DEL'] - annotations = ['assert_total','lib','link','include','provide','access', - 'default'] + directives = ['lib','link','flag','include','hide','freeze','access', + 'default','logging','dynamic','name','error_handlers','language'] tokens = { 'root': [ + # Comments + (r'^(\s*)(%%%s)' % '|'.join(directives), + bygroups(Text, Keyword.Reserved)), + (r'(\s*)(--(?![!#$%&*+./<=>?@\^|_~:\\]).*?)$', bygroups(Text, Comment.Single)), + (r'(\s*)(\|{3}.*?)$', bygroups(Text, Comment.Single)), + (r'(\s*)({-)', bygroups(Text, Comment.Multiline), 'comment'), # Declaration (r'^(\s*)([^\s\(\)\{\}]+)(\s*)(:)(\s*)', bygroups(Text, Name.Function, Text, Operator.Word, Text)), - # Comments - (r'^(\s*)(%%%s)' % '|'.join(annotations), - bygroups(Text, Keyword.Reserved)), - (r'--(?![!#$%&*+./<=>?@\^|_~:\\]).*?$', Comment.Single), - (r'{-', Comment.Multiline, 'comment'), # Identifiers (r'\b(%s)(?!\')\b' % '|'.join(reserved), Keyword.Reserved), (r'(import|module)(\s+)', bygroups(Keyword.Reserved, Text), 'module'), @@ -3135,7 +3136,7 @@ def gen_elixir_string_rules(name, symbol, token): (r'[^#%s\\]+' % (symbol,), token), include('escapes'), (r'\\.', token), - (r'(%s)(:?)' % (symbol,), bygroups(token, Punctuation), "#pop"), + (r'(%s)' % (symbol,), bygroups(token), "#pop"), include('interpol') ] return states @@ -3169,7 +3170,7 @@ class ElixirLexer(RegexLexer): mimetypes = ['text/x-elixir'] KEYWORD = ['fn', 'do', 'end', 'after', 'else', 'rescue', 'catch'] - KEYWORD_OPERATOR = ['not', 'and', 'or', 'xor', 'when', 'in'] + KEYWORD_OPERATOR = ['not', 'and', 'or', 'when', 'in'] BUILTIN = [ 'case', 'cond', 'for', 'if', 'unless', 'try', 'receive', 'raise', 'quote', 'unquote', 'unquote_splicing', 'throw', 'super' @@ -3184,15 +3185,19 @@ class ElixirLexer(RegexLexer): PSEUDO_VAR = ['_', '__MODULE__', '__DIR__', '__ENV__', '__CALLER__'] - OPERATORS3 = ['<<<', '>>>', '|||', '&&&', '^^^', '~~~', '===', '!=='] + + OPERATORS3 = [ + '<<<', '>>>', '|||', '&&&', '^^^', '~~~', '===', '!==', + '~>>', '<~>', '|~>', '<|>', + ] OPERATORS2 = [ - '==', '!=', '<=', '>=', '&&', '||', '<>', '++', '--', '|>', '=~' + '==', '!=', '<=', '>=', '&&', '||', '<>', '++', '--', '|>', '=~', + '->', '<-', '|', '.', '=', '~>', '<~', ] OPERATORS1 = ['<', '>', '+', '-', '*', '/', '!', '^', '&'] PUNCTUATION = [ - '\\\\', '<<', '>>', '::', '->', '<-', '=>', '|', '(', ')', - '{', '}', ';', ',', '.', '[', ']', '%', '=' + '\\\\', '<<', '>>', '=>', '(', ')', ':', ';', ',', '[', ']' ] def get_tokens_unprocessed(self, text): @@ -3218,20 +3223,19 @@ class ElixirLexer(RegexLexer): yield index, token, value def gen_elixir_sigil_rules(): - # these braces are balanced inside the sigil string - braces = [ + # all valid sigil terminators (excluding heredocs) + terminators = [ (r'\{', r'\}', 'cb'), (r'\[', r'\]', 'sb'), (r'\(', r'\)', 'pa'), (r'\<', r'\>', 'ab'), + (r'/', r'/', 'slas'), + (r'\|', r'\|', 'pipe'), + ('"', '"', 'quot'), + ("'", "'", 'apos'), ] - # these are also valid sigil terminators, they are not balanced - terms = [ - (r'/', 'slas'), (r'\|', 'pipe'), ('"', 'quot'), ("'", 'apos'), - ] - - # heredocs have slightly different rules, they are not balanced + # heredocs have slightly different rules triquotes = [(r'"""', 'triquot'), (r"'''", 'triapos')] token = String.Other @@ -3255,33 +3259,14 @@ class ElixirLexer(RegexLexer): include('heredoc_no_interpol'), ] - for term, name in terms: + for lterm, rterm, name in terminators: states['sigils'] += [ - (r'~[a-z]' + term, token, name + '-intp'), - (r'~[A-Z]' + term, token, name + '-no-intp'), + (r'~[a-z]' + lterm, token, name + '-intp'), + (r'~[A-Z]' + lterm, token, name + '-no-intp'), ] - - # Similar states to the braced sigils, but no balancing of - # terminators - states[name +'-intp'] = gen_elixir_sigstr_rules(term, token) + states[name +'-intp'] = gen_elixir_sigstr_rules(rterm, token) states[name +'-no-intp'] = \ - gen_elixir_sigstr_rules(term, token, interpol=False) - - for lbrace, rbrace, name in braces: - states['sigils'] += [ - (r'~[a-z]' + lbrace, token, name + '-intp'), - (r'~[A-Z]' + lbrace, token, name + '-no-intp') - ] - - states[name +'-intp'] = [ - (r'\\.', token), - (lbrace, token, '#push'), - ] + gen_elixir_sigstr_rules(rbrace, token) - - states[name +'-no-intp'] = [ - (r'\\.', token), - (lbrace, token, '#push'), - ] + gen_elixir_sigstr_rules(rbrace, token, interpol=False) + gen_elixir_sigstr_rules(rterm, token, interpol=False) return states @@ -3290,28 +3275,35 @@ class ElixirLexer(RegexLexer): op1_re = "|".join(re.escape(s) for s in OPERATORS1) ops_re = r'(?:%s|%s|%s)' % (op3_re, op2_re, op1_re) punctuation_re = "|".join(re.escape(s) for s in PUNCTUATION) - name_re = r'[a-z_][a-zA-Z_0-9]*[!\?]?' - modname_re = r'[A-Z][A-Za-z_]*(?:\.[A-Z][A-Za-z_]*)*' + alnum = '[A-Za-z_0-9]' + name_re = r'(?:\.\.\.|[a-z_]%s*[!\?]?)' % alnum + modname_re = r'[A-Z]%(alnum)s*(?:\.[A-Z]%(alnum)s*)*' % {'alnum': alnum} complex_name_re = r'(?:%s|%s|%s)' % (name_re, modname_re, ops_re) special_atom_re = r'(?:\.\.\.|<<>>|%{}|%|{})' + long_hex_char_re = r'(\\x{)([\da-fA-F]+)(})' + hex_char_re = r'(\\x[\da-fA-F]{1,2})' + escape_char_re = r'(\\[abdefnrstv])' + tokens = { 'root': [ (r'\s+', Text), (r'#.*$', Comment.Single), # Various kinds of characters - (r'(?i)(\?)(\\x{)([\da-f]+)(})', + (r'(\?)' + long_hex_char_re, bygroups(String.Char, String.Escape, Number.Hex, String.Escape)), - (r'(?i)(\?)(\\x[\da-f]{1,2})', - bygroups(String.Char, String.Escape)), - (r'(\?)(\\[0-7]{1,3})', + (r'(\?)' + hex_char_re, bygroups(String.Char, String.Escape)), - (r'(\?)(\\[abdefnrstv])', + (r'(\?)' + escape_char_re, bygroups(String.Char, String.Escape)), (r'\?\\?.', String.Char), + # '::' has to go before atoms + (r':::', String.Symbol), + (r'::', Operator), + # atoms (r':' + special_atom_re, String.Symbol), (r':' + complex_name_re, String.Symbol), @@ -3325,6 +3317,10 @@ class ElixirLexer(RegexLexer): # @attributes (r'@' + name_re, Name.Attribute), + # identifiers + (name_re, Name), + (r'(%%?)(%s)' % (modname_re,), bygroups(Punctuation, Name.Class)), + # operators and punctuation (op3_re, Operator), (op2_re, Operator), @@ -3332,14 +3328,10 @@ class ElixirLexer(RegexLexer): (r'&\d', Name.Entity), # anon func arguments (op1_re, Operator), - # identifiers - (name_re, Name), - (modname_re, Name.Class), - # numbers - (r'0[bB][01]+', Number.Bin), - (r'0[0-7]+', Number.Oct), - (r'(?i)0x[\da-f]+', Number.Hex), + (r'0b[01]+', Number.Bin), + (r'0o[0-7]+', Number.Oct), + (r'0x[\da-fA-F]+', Number.Hex), (r'\d(_?\d)*\.\d(_?\d)*([eE][-+]?\d(_?\d)*)?', Number.Float), (r'\d(_?\d)*', Number.Integer), @@ -3350,6 +3342,9 @@ class ElixirLexer(RegexLexer): (r"'", String.Single, 'string_single'), include('sigils'), + + (r'%{', Punctuation, 'map_key'), + (r'{', Punctuation, 'tuple'), ], 'heredoc_double': [ (r'^\s*"""', String.Heredoc, '#pop'), @@ -3372,11 +3367,10 @@ class ElixirLexer(RegexLexer): (r'\n+', String.Heredoc), ], 'escapes': [ - (r'(?i)(\\x{)([\da-f]+)(})', + (long_hex_char_re, bygroups(String.Escape, Number.Hex, String.Escape)), - (r'(?i)\\x[\da-f]{1,2}', String.Escape), - (r'\\[0-7]{1,3}', String.Escape), - (r'\\[abdefnrstv]', String.Escape), + (hex_char_re, String.Escape), + (escape_char_re, String.Escape), ], 'interpol': [ (r'#{', String.Interpol, 'interpol_string'), @@ -3385,6 +3379,21 @@ class ElixirLexer(RegexLexer): (r'}', String.Interpol, "#pop"), include('root') ], + 'map_key': [ + include('root'), + (r':', Punctuation, 'map_val'), + (r'=>', Punctuation, 'map_val'), + (r'}', Punctuation, '#pop'), + ], + 'map_val': [ + include('root'), + (r',', Punctuation, '#pop'), + (r'(?=})', Punctuation, '#pop'), + ], + 'tuple': [ + include('root'), + (r'}', Punctuation, '#pop'), + ], } tokens.update(gen_elixir_string_rules('double', '"', String.Double)) tokens.update(gen_elixir_string_rules('single', "'", String.Single)) diff --git a/pygments/lexers/jvm.py b/pygments/lexers/jvm.py index fa05b7ed..0d16e2fd 100644 --- a/pygments/lexers/jvm.py +++ b/pygments/lexers/jvm.py @@ -1219,6 +1219,7 @@ class GoloLexer(RegexLexer): (r'-?\d[\d_]*', Number.Integer), ('`?[a-zA-Z_][\w$]*', Name), + (r'@[a-zA-Z_][\w$._]*', Name.Decorator), (r'"""', String, combined('stringescape', 'triplestring')), (r'"', String, combined('stringescape', 'doublestring')), diff --git a/pygments/lexers/other.py b/pygments/lexers/other.py index 608e499d..0075fc07 100644 --- a/pygments/lexers/other.py +++ b/pygments/lexers/other.py @@ -2473,7 +2473,7 @@ class ProtoBufLexer(RegexLexer): (r'/(\\\n)?/(\n|(.|\n)*?[^\\]\n)', Comment.Single), (r'/(\\\n)?\*(.|\n)*?\*(\\\n)?/', Comment.Multiline), (r'\b(import|option|optional|required|repeated|default|packed|' - r'ctype|extensions|to|max|rpc|returns)\b', Keyword), + r'ctype|extensions|to|max|rpc|returns|oneof)\b', Keyword), (r'(int32|int64|uint32|uint64|sint32|sint64|' r'fixed32|fixed64|sfixed32|sfixed64|' r'float|double|bool|string|bytes)\b', Keyword.Type), diff --git a/pygments/lexers/sql.py b/pygments/lexers/sql.py index 7540f079..5070d487 100644 --- a/pygments/lexers/sql.py +++ b/pygments/lexers/sql.py @@ -464,10 +464,9 @@ class MySqlLexer(RegexLexer): (r'/\*', Comment.Multiline, 'multiline-comments'), (r'[0-9]+', Number.Integer), (r'[0-9]*\.[0-9]+(e[+-][0-9]+)', Number.Float), - # TODO: add backslash escapes - (r"'(''|[^'])*'", String.Single), - (r'"(""|[^"])*"', String.Double), - (r"`(``|[^`])*`", String.Symbol), + (r"'(\\\\|\\'|''|[^'])*'", String.Single), + (r'"(\\\\|\\"|""|[^"])*"', String.Double), + (r"`(\\\\|\\`|``|[^`])*`", String.Symbol), (r'[+*/<>=~!@#%^&|`?-]', Operator), (r'\b(tinyint|smallint|mediumint|int|integer|bigint|date|' r'datetime|time|bit|bool|tinytext|mediumtext|longtext|text|' diff --git a/tests/examplefiles/99_bottles_of_beer.chpl b/tests/examplefiles/99_bottles_of_beer.chpl index f73be7b1..47fcaaf6 100644 --- a/tests/examplefiles/99_bottles_of_beer.chpl +++ b/tests/examplefiles/99_bottles_of_beer.chpl @@ -112,7 +112,50 @@ c = nil; c = new Oval(r=1.0, r2=2.0); writeln("Area of oval: " + c.area()); +// This is a valid decimal integer: +var x = 0000000000012; + union U { var i: int; var r: real; } + +// chapel ranges are awesome. +var r1 = 1..10, // 1 2 3 4 5 6 7 8 9 10 + r2 = 10..1, // no values in this range + r3 = 1..10 by -1, // 10 9 8 7 6 5 4 3 2 1 + r4 = 1..10 by 2, // 1 3 5 7 9 + r5 = 1..10 by 2 align 0, // 2 4 6 8 10 + r6 = 1..10 by 2 align 2, // 2 4 6 8 10 + r7 = 1..10 # 3, // 1 2 3 + r8 = 1..10 # -2, // 9 10 + r9 = 1..100 # 10 by 2, // 1 3 5 7 9 + ra = 1..100 by 2 # 10, // 1 3 5 7 9 11 13 15 17 19 + rb = 1.. # 100 by 10; // 1 11 21 31 41 51 61 71 81 91 + +// create a variable with default initialization +var myVarWithoutInit: real = noinit; +myVarWithoutInit = 1.0; + +// Chapel has <~> operator for read and write I/O operations. +class IntPair { + var x: int; + var y: int; + proc readWriteThis(f) { + f <~> x <~> new ioLiteral(",") <~> y <~> new ioNewline(); + } +} +var ip = new IntPair(17,2); +write(ip); + +var targetDom: {1..10}, + target: [targetDom] int; +coforall i in targetDom with (ref target) { + targetDom[i] = i ** 3; +} + +var wideOpen = 0o777, + mememe = 0o600, + clique_y = 0O660, + zeroOct = 0o0, + minPosOct = 0O1; diff --git a/tests/examplefiles/all.nit b/tests/examplefiles/all.nit new file mode 100644 index 00000000..d4e1ddfa --- /dev/null +++ b/tests/examplefiles/all.nit @@ -0,0 +1,1986 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net> +# +# 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. + +import gtk + +class CalculatorContext + var result : nullable Float = null + + var last_op : nullable Char = null + + var current : nullable Float = null + var after_point : nullable Int = null + + fun push_op( op : Char ) + do + apply_last_op_if_any + if op == 'C' then + self.result = 0.0 + last_op = null + else + last_op = op # store for next push_op + end + + # prepare next current + after_point = null + current = null + end + + fun push_digit( digit : Int ) + do + var current = current + if current == null then current = 0.0 + + var after_point = after_point + if after_point == null then + current = current * 10.0 + digit.to_f + else + current = current + digit.to_f * 10.0.pow(after_point.to_f) + self.after_point -= 1 + end + + self.current = current + end + + fun switch_to_decimals + do + if self.current == null then current = 0.0 + if after_point != null then return + + after_point = -1 + end + + fun apply_last_op_if_any + do + var op = last_op + + var result = result + if result == null then result = 0.0 + + var current = current + if current == null then current = 0.0 + + if op == null then + result = current + else if op == '+' then + result = result + current + else if op == '-' then + result = result - current + else if op == '/' then + result = result / current + else if op == '*' then + result = result * current + end + self.result = result + self.current = null + end +end + +class CalculatorGui + super GtkCallable + + var win : GtkWindow + var container : GtkGrid + + var lbl_disp : GtkLabel + var but_eq : GtkButton + var but_dot : GtkButton + + var context = new CalculatorContext + + redef fun signal( sender, user_data ) + do + var after_point = context.after_point + if after_point == null then + after_point = 0 + else + after_point = (after_point.abs) + end + + if user_data isa Char then # is an operation + var c = user_data + if c == '.' then + but_dot.sensitive= false + context.switch_to_decimals + lbl_disp.text = "{context.current.to_i}." + else + but_dot.sensitive= true + context.push_op( c ) + + var s = context.result.to_precision_native(6) + var index : nullable Int = null + for i in s.length.times do + var chiffre = s.chars[i] + if chiffre == '0' and index == null then + index = i + else if chiffre != '0' then + index = null + end + end + if index != null then + s = s.substring(0, index) + if s.chars[s.length-1] == ',' then s = s.substring(0, s.length-1) + end + lbl_disp.text = s + end + else if user_data isa Int then # is a number + var n = user_data + context.push_digit( n ) + lbl_disp.text = context.current.to_precision_native(after_point) + end + end + + init + do + init_gtk + + win = new GtkWindow( 0 ) + + container = new GtkGrid(5,5,true) + win.add( container ) + + lbl_disp = new GtkLabel( "_" ) + container.attach( lbl_disp, 0, 0, 5, 1 ) + + # digits + for n in [0..9] do + var but = new GtkButton.with_label( n.to_s ) + but.request_size( 64, 64 ) + but.signal_connect( "clicked", self, n ) + if n == 0 then + container.attach( but, 0, 4, 1, 1 ) + else container.attach( but, (n-1)%3, 3-(n-1)/3, 1, 1 ) + end + + # operators + var r = 1 + for op in ['+', '-', '*', '/' ] do + var but = new GtkButton.with_label( op.to_s ) + but.request_size( 64, 64 ) + but.signal_connect( "clicked", self, op ) + container.attach( but, 3, r, 1, 1 ) + r+=1 + end + + # = + but_eq = new GtkButton.with_label( "=" ) + but_eq.request_size( 64, 64 ) + but_eq.signal_connect( "clicked", self, '=' ) + container.attach( but_eq, 4, 3, 1, 2 ) + + # . + but_dot = new GtkButton.with_label( "." ) + but_dot.request_size( 64, 64 ) + but_dot.signal_connect( "clicked", self, '.' ) + container.attach( but_dot, 1, 4, 1, 1 ) + + #C + var but_c = new GtkButton.with_label( "C" ) + but_c.request_size( 64, 64 ) + but_c.signal_connect("clicked", self, 'C') + container.attach( but_c, 2, 4, 1, 1 ) + + win.show_all + end +end + +# context tests +var context = new CalculatorContext +context.push_digit( 1 ) +context.push_digit( 2 ) +context.push_op( '+' ) +context.push_digit( 3 ) +context.push_op( '*' ) +context.push_digit( 2 ) +context.push_op( '=' ) +var r = context.result.to_precision( 2 ) +assert r == "30.00" else print r + +context = new CalculatorContext +context.push_digit( 1 ) +context.push_digit( 4 ) +context.switch_to_decimals +context.push_digit( 1 ) +context.push_op( '*' ) +context.push_digit( 3 ) +context.push_op( '=' ) +r = context.result.to_precision( 2 ) +assert r == "42.30" else print r + +context.push_op( '+' ) +context.push_digit( 1 ) +context.push_digit( 1 ) +context.push_op( '=' ) +r = context.result.to_precision( 2 ) +assert r == "53.30" else print r + +context = new CalculatorContext +context.push_digit( 4 ) +context.push_digit( 2 ) +context.switch_to_decimals +context.push_digit( 3 ) +context.push_op( '/' ) +context.push_digit( 3 ) +context.push_op( '=' ) +r = context.result.to_precision( 2 ) +assert r == "14.10" else print r + +#test multiple decimals +context = new CalculatorContext +context.push_digit( 5 ) +context.push_digit( 0 ) +context.switch_to_decimals +context.push_digit( 1 ) +context.push_digit( 2 ) +context.push_digit( 3 ) +context.push_op( '+' ) +context.push_digit( 1 ) +context.push_op( '=' ) +r = context.result.to_precision( 3 ) +assert r == "51.123" else print r + +#test 'C' button +context = new CalculatorContext +context.push_digit( 1 ) +context.push_digit( 0 ) +context.push_op( '+' ) +context.push_digit( 1 ) +context.push_digit( 0 ) +context.push_op( '=' ) +context.push_op( 'C' ) +r = context.result.to_precision( 1 ) +assert r == "0.0" else print r + +# graphical application + +if "NIT_TESTING".environ != "true" then + var app = new CalculatorGui + run_gtk +end +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> +# +# 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. + +# This sample has been implemented to show you how simple is it to play +# with native callbacks (C) through an high level with NIT program. + +module callback_chimpanze +import callback_monkey + +class Chimpanze + super MonkeyActionCallable + + fun create + do + var monkey = new Monkey + print "Hum, I'm sleeping ..." + # Invoking method which will take some time to compute, and + # will be back in wokeUp method with information. + # - Callback method defined in MonkeyActionCallable Interface + monkey.wokeUpAction(self, "Hey, I'm awake.") + end + + # Inherit callback method, defined by MonkeyActionCallable interface + # - Back of wokeUpAction method + redef fun wokeUp( sender:Monkey, message:Object ) + do + print message + end +end + +var m = new Chimpanze +m.create +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> +# +# 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. + +# This sample has been implemented to show you how simple is it to play +# with native callbacks (C) through an high level with NIT program. + +module callback_monkey + +in "C header" `{ + #include <stdio.h> + #include <stdlib.h> + + typedef struct { + int id; + int age; + } CMonkey; + + typedef struct { + MonkeyActionCallable toCall; + Object message; + } MonkeyAction; +`} + +in "C body" `{ + // Method which reproduce a callback answer + // Please note that a function pointer is only used to reproduce the callback + void cbMonkey(CMonkey *mkey, void callbackFunc(CMonkey*, MonkeyAction*), MonkeyAction *data) + { + sleep(2); + callbackFunc( mkey, data ); + } + + // Back of background treatment, will be redirected to callback function + void nit_monkey_callback_func( CMonkey *mkey, MonkeyAction *data ) + { + // To call a your method, the signature must be written like this : + // <Interface Name>_<Method>... + MonkeyActionCallable_wokeUp( data->toCall, mkey, data->message ); + } +`} + +# Implementable interface to get callback in defined methods +interface MonkeyActionCallable + fun wokeUp( sender:Monkey, message: Object) is abstract +end + +# Defining my object type Monkey, which is, in a low level, a pointer to a C struct (CMonkey) +extern class Monkey `{ CMonkey * `} + + new `{ + CMonkey *monkey = malloc( sizeof(CMonkey) ); + monkey->age = 10; + monkey->id = 1; + return monkey; + `} + + # Object method which will get a callback in wokeUp method, defined in MonkeyActionCallable interface + # Must be defined as Nit/C method because of C call inside + fun wokeUpAction( toCall: MonkeyActionCallable, message: Object ) is extern import MonkeyActionCallable.wokeUp `{ + + // Allocating memory to keep reference of received parameters : + // - Object receiver + // - Message + MonkeyAction *data = malloc( sizeof(MonkeyAction) ); + + // Incrementing reference counter to prevent from releasing + MonkeyActionCallable_incr_ref( toCall ); + Object_incr_ref( message ); + + data->toCall = toCall; + data->message = message; + + // Calling method which reproduce a callback by passing : + // - Receiver + // - Function pointer to object return method + // - Datas + cbMonkey( recv, &nit_monkey_callback_func, data ); + `} +end +# 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. + +# Implementation of circular lists +# This example shows the usage of generics and somewhat a specialisation of collections. +module circular_list + +# Sequences of elements implemented with a double-linked circular list +class CircularList[E] + # Like standard Array or LinkedList, CircularList is a Sequence. + super Sequence[E] + + # The first node of the list if any + # The special case of an empty list is handled by a null node + private var node: nullable CLNode[E] = null + + redef fun iterator do return new CircularListIterator[E](self) + + redef fun first do return self.node.item + + redef fun push(e) + do + var new_node = new CLNode[E](e) + var n = self.node + if n == null then + # the first node + self.node = new_node + else + # not the first one, so attach nodes correctly. + var old_last_node = n.prev + new_node.next = n + new_node.prev = old_last_node + old_last_node.next = new_node + n.prev = new_node + end + end + + redef fun pop + do + var n = self.node + assert n != null + var prev = n.prev + if prev == n then + # the only node + self.node = null + return n.item + end + # not the only one do detach nodes correctly. + var prev_prev = prev.prev + n.prev = prev_prev + prev_prev.next = n + return prev.item + end + + redef fun unshift(e) + do + # Circularity has benefits. + push(e) + self.node = self.node.prev + end + + redef fun shift + do + # Circularity has benefits. + self.node = self.node.next + return self.pop + end + + # Move the first at the last position, the second at the first, etc. + fun rotate + do + var n = self.node + if n == null then return + self.node = n.next + end + + # Sort the list using the Josephus algorithm. + fun josephus(step: Int) + do + var res = new CircularList[E] + while not self.is_empty do + # count 'step' + for i in [1..step[ do self.rotate + # kill + var x = self.shift + res.add(x) + end + self.node = res.node + end +end + +# Nodes of a CircularList +private class CLNode[E] + # The current item + var item: E + + # The next item in the circular list. + # Because of circularity, there is always a next; + # so by default let it be self + var next: CLNode[E] = self + + # The previous item in the circular list. + # Coherence between next and previous nodes has to be maintained by the + # circular list. + var prev: CLNode[E] = self +end + +# An iterator of a CircularList. +private class CircularListIterator[E] + super IndexedIterator[E] + + redef var index: Int + + # The current node pointed. + # Is null if the list is empty. + var node: nullable CLNode[E] + + # The list iterated. + var list: CircularList[E] + + redef fun is_ok + do + # Empty lists are not OK. + # Pointing again the first node is not OK. + return self.node != null and (self.index == 0 or self.node != self.list.node) + end + + redef fun next + do + self.node = self.node.next + self.index += 1 + end + + redef fun item do return self.node.item + + init(list: CircularList[E]) + do + self.node = list.node + self.list = list + self.index = 0 + end +end + +var i = new CircularList[Int] +i.add_all([1, 2, 3, 4, 5, 6, 7]) +print i.first +print i.join(":") + +i.push(8) +print i.shift +print i.pop +i.unshift(0) +print i.join(":") + +i.josephus(3) +print i.join(":") +# 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. + +# This module beef up the clock module by allowing a clock to be comparable. +# It show the usage of class refinement +module clock_more + +import clock + +redef class Clock + # Clock are now comparable + super Comparable + + # Comparaison of a clock make only sense with an other clock + redef type OTHER: Clock + + redef fun <(o) + do + # Note: < is the only abstract method of Comparable. + # All other operators and methods rely on < and ==. + return self.total_minutes < o.total_minutes + end +end + +var c1 = new Clock(8, 12) +var c2 = new Clock(8, 13) +var c3 = new Clock(9, 13) + +print "{c1}<{c2}? {c1<c2}" +print "{c1}<={c2}? {c1<=c2}" +print "{c1}>{c2}? {c1>c2}" +print "{c1}>={c2}? {c1>=c2}" +print "{c1}<=>{c2}? {c1<=>c2}" +print "{c1},{c2}? max={c1.max(c2)} min={c1.min(c2)}" +print "{c1}.is_between({c2}, {c3})? {c1.is_between(c2, c3)}" +print "{c2}.is_between({c1}, {c3})? {c2.is_between(c1, c3)}" + +print "-" + +c1.minutes += 1 + +print "{c1}<{c2}? {c1<c2}" +print "{c1}<={c2}? {c1<=c2}" +print "{c1}>{c2}? {c1>c2}" +print "{c1}>={c2}? {c1>=c2}" +print "{c1}<=>{c2}? {c1<=>c2}" +print "{c1},{c2}? max={c1.max(c2)} min={c1.min(c2)}" +print "{c1}.is_between({c2}, {c3})? {c1.is_between(c2, c3)}" +print "{c2}.is_between({c1}, {c3})? {c2.is_between(c1, c3)}" +# 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. + +# This module provide a simple wall clock. +# It is an example of getters and setters. +# A beefed-up module is available in clock_more +module clock + +# A simple wall clock with 60 minutes and 12 hours. +class Clock + # total number of minutes from 0 to 719 + var total_minutes: Int + # Note: only the read acces is public, the write access is private. + + # number of minutes in the current hour (from 0 to 59) + fun minutes: Int do return self.total_minutes % 60 + + # set the number of minutes in the current hour. + # if m < 0 or m >= 60, the hour will be changed accordinlgy + fun minutes=(m: Int) do self.total_minutes = self.hours * 60 + m + + # number of hours (from 0 to 11) + fun hours: Int do return self.total_minutes / 60 + + # set the number of hours + # the minutes will not be updated + fun hours=(h: Int) do self.total_minutes = h * 60 + minutes + + # the position of the hour arrow in the [0..60[ interval + fun hour_pos: Int do return total_minutes / 12 + + # replace the arrow of hours (from 0 to 59). + # the hours and the minutes will be updated. + fun hour_pos=(h: Int) do self.total_minutes = h * 12 + + redef fun to_s do return "{hours}:{minutes}" + + fun reset(hours, minutes: Int) do self.total_minutes = hours*60 + minutes + + init(hours, minutes: Int) do self.reset(hours, minutes) + + redef fun ==(o) + do + # Note: o is a nullable Object, a type test is required + # Thanks to adaptive typing, there is no downcast + # i.e. the code is safe! + return o isa Clock and self.total_minutes == o.total_minutes + end +end + +var c = new Clock(10,50) +print "It's {c} o'clock." + +c.minutes += 22 +print "Now it's {c} o'clock." + +print "The short arrow in on the {c.hour_pos/5} and the long arrow in on the {c.minutes/5}." + +c.hours -= 2 +print "Now it's {c} o'clock." + +var c2 = new Clock(9, 11) +print "It's {c2} on the second clock." +print "The two clocks are synchronized: {c == c2}." +c2.minutes += 1 +print "It's now {c2} on the second clock." +print "The two clocks are synchronized: {c == c2}." +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> +# +# 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. + +# Sample of the Curl module. +module curl_http + +import curl + +# Small class to represent an Http Fetcher +class MyHttpFetcher + super CurlCallbacks + + var curl: Curl + var our_body: String = "" + + init(curl: Curl) do self.curl = curl + + # Release curl object + fun destroy do self.curl.destroy + + # Header callback + redef fun header_callback(line: String) do + # We keep this callback silent for testing purposes + #if not line.has_prefix("Date:") then print "Header_callback : {line}" + end + + # Body callback + redef fun body_callback(line: String) do self.our_body = "{self.our_body}{line}" + + # Stream callback - Cf : No one is registered + redef fun stream_callback(buffer: String, size: Int, count: Int) do print "Stream_callback : {buffer} - {size} - {count}" +end + + +# Program +if args.length < 2 then + print "Usage: curl_http <method wished [POST, GET, GET_FILE]> <target url>" +else + var curl = new Curl + var url = args[1] + var request = new CurlHTTPRequest(url, curl) + + # HTTP Get Request + if args[0] == "GET" then + request.verbose = false + var getResponse = request.execute + + if getResponse isa CurlResponseSuccess then + print "Status code : {getResponse.status_code}" + print "Body : {getResponse.body_str}" + else if getResponse isa CurlResponseFailed then + print "Error code : {getResponse.error_code}" + print "Error msg : {getResponse.error_msg}" + end + + # HTTP Post Request + else if args[0] == "POST" then + var myHttpFetcher = new MyHttpFetcher(curl) + request.delegate = myHttpFetcher + + var postDatas = new HeaderMap + postDatas["Bugs Bunny"] = "Daffy Duck" + postDatas["Batman"] = "Robin likes special characters @#ùà!è§'(\"é&://,;<>∞~*" + postDatas["Batman"] = "Yes you can set multiple identical keys, but APACHE will consider only once, the last one" + request.datas = postDatas + request.verbose = false + var postResponse = request.execute + + print "Our body from the callback : {myHttpFetcher.our_body}" + + if postResponse isa CurlResponseSuccess then + print "*** Answer ***" + print "Status code : {postResponse.status_code}" + print "Body should be empty, because we decided to manage callbacks : {postResponse.body_str.length}" + else if postResponse isa CurlResponseFailed then + print "Error code : {postResponse.error_code}" + print "Error msg : {postResponse.error_msg}" + end + + # HTTP Get to file Request + else if args[0] == "GET_FILE" then + var headers = new HeaderMap + headers["Accept"] = "Moo" + request.headers = headers + request.verbose = false + var downloadResponse = request.download_to_file(null) + + if downloadResponse isa CurlFileResponseSuccess then + print "*** Answer ***" + print "Status code : {downloadResponse.status_code}" + print "Size downloaded : {downloadResponse.size_download}" + else if downloadResponse isa CurlResponseFailed then + print "Error code : {downloadResponse.error_code}" + print "Error msg : {downloadResponse.error_msg}" + end + # Program logic + else + print "Usage : Method[POST, GET, GET_FILE]" + end +end +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> +# +# 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. + +# Mail sender sample using the Curl module +module curl_mail + +import curl + +var curl = new Curl +var mail_request = new CurlMailRequest(curl) + +# Networks +var response = mail_request.set_outgoing_server("smtps://smtp.example.org:465", "user@example.org", "mypassword") +if response isa CurlResponseFailed then + print "Error code : {response.error_code}" + print "Error msg : {response.error_msg}" +end + +# Headers +mail_request.from = "Billy Bob" +mail_request.to = ["user@example.org"] +mail_request.cc = ["bob@example.org"] +mail_request.bcc = null + +var headers_body = new HeaderMap +headers_body["Content-Type:"] = "text/html; charset=\"UTF-8\"" +headers_body["Content-Transfer-Encoding:"] = "quoted-printable" +mail_request.headers_body = headers_body + +# Content +mail_request.body = "<h1>Here you can write HTML stuff.</h1>" +mail_request.subject = "Hello From My Nit Program" + +# Others +mail_request.verbose = false + +# Send mail +response = mail_request.execute +if response isa CurlResponseFailed then + print "Error code : {response.error_code}" + print "Error msg : {response.error_msg}" +else if response isa CurlMailResponseSuccess then + print "Mail Sent" +else + print "Unknown Curl Response type" +end +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2012-2013 Alexis Laferrière <alexis.laf@xymus.net> +# +# 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. + +# Draws an arithmetic operation to the terminal +module draw_operation + +redef enum Int + fun n_chars: Int `{ + int c; + if ( abs(recv) >= 10 ) + c = 1+(int)log10f( (float)abs(recv) ); + else + c = 1; + if ( recv < 0 ) c ++; + return c; + `} +end + +redef enum Char + fun as_operator(a, b: Int): Int + do + if self == '+' then return a + b + if self == '-' then return a - b + if self == '*' then return a * b + if self == '/' then return a / b + if self == '%' then return a % b + abort + end + + fun override_dispc: Bool + do + return self == '+' or self == '-' or self == '*' or self == '/' or self == '%' + end + + fun lines(s: Int): Array[Line] + do + if self == '+' then + return [new Line(new P(0,s/2),1,0,s), new Line(new P(s/2,1),0,1,s-2)] + else if self == '-' then + return [new Line(new P(0,s/2),1,0,s)] + else if self == '*' then + var lines = new Array[Line] + for y in [1..s-1[ do + lines.add( new Line(new P(1,y), 1,0,s-2) ) + end + return lines + else if self == '/' then + return [new Line(new P(s-1,0), -1,1, s )] + else if self == '%' then + var q4 = s/4 + var lines = [new Line(new P(s-1,0),-1,1,s)] + for l in [0..q4[ do + lines.append([ new Line( new P(0,l), 1,0,q4), new Line( new P(s-1,s-1-l), -1,0,q4) ]) + end + return lines + else if self == '1' then + return [new Line(new P(s/2,0), 0,1,s),new Line(new P(0,s-1),1,0,s), + new Line( new P(s/2,0),-1,1,s/2)] + else if self == '2' then + return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s/2), + new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 0,1,s/2), + new Line( new P(0,s/2), 1,0,s)] + else if self == '3' then + return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), + new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 1,0,s)] + else if self == '4' then + return [new Line(new P(s-1,0),0,1,s), new Line( new P(0,0), 0,1,s/2), + new Line( new P(0,s/2), 1,0,s)] + else if self == '5' then + return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2), + new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2), + new Line( new P(0,s/2), 1,0,s)] + else if self == '6' then + return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2), + new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s), + new Line( new P(0,s/2), 1,0,s)] + else if self == '7' then + var tl = new P(0,0) + var tr = new P(s-1,0) + return [new Line(tl, 1,0,s), new Line(tr,-1,1,s)] + else if self == '8' then + return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), + new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s), + new Line( new P(0,s/2), 1,0,s)] + else if self == '9' then + return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), + new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2), + new Line( new P(0,s/2), 1,0,s)] + else if self == '0' then + return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s), + new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s)] + end + return new Array[Line] + end +end + +class P + var x : Int + var y : Int +end + +redef class String + # hack is to support a bug in the evaluation software + fun draw(dispc: Char, size, gap: Int, hack: Bool) + do + var w = size * length +(length-1)*gap + var h = size + var map = new Array[Array[Char]] + for x in [0..w[ do + map[x] = new Array[Char].filled_with( ' ', h ) + end + + var ci = 0 + for c in self.chars do + var local_dispc + if c.override_dispc then + local_dispc = c + else + local_dispc = dispc + end + + var lines = c.lines( size ) + for line in lines do + var x = line.o.x+ci*size + x += ci*gap + var y = line.o.y + for s in [0..line.len[ do + assert map.length > x and map[x].length > y else print "setting {x},{y} as {local_dispc}" + map[x][y] = local_dispc + x += line.step_x + y += line.step_y + end + end + + ci += 1 + end + + if hack then + for c in [0..size[ do + map[c][0] = map[map.length-size+c][0] + map[map.length-size+c][0] = ' ' + end + end + + for y in [0..h[ do + for x in [0..w[ do + printn map[x][y] + end + print "" + end + end +end + +class Line + var o : P + var step_x : Int + var step_y : Int + var len : Int +end + +var a +var b +var op_char +var disp_char +var disp_size +var disp_gap + +if "NIT_TESTING".environ == "true" then + a = 567 + b = 13 + op_char = '*' + disp_char = 'O' + disp_size = 8 + disp_gap = 1 +else + printn "Left operand: " + a = gets.to_i + + printn "Right operand: " + b = gets.to_i + + printn "Operator (+, -, *, /, %): " + op_char = gets.chars[0] + + printn "Char to display: " + disp_char = gets.chars[0] + + printn "Size of text: " + disp_size = gets.to_i + + printn "Space between digits: " + disp_gap = gets.to_i +end + +var result = op_char.as_operator( a, b ) + +var len_a = a.n_chars +var len_b = b.n_chars +var len_res = result.n_chars +var max_len = len_a.max( len_b.max( len_res ) ) + 1 + +# draw first line +var d = max_len - len_a +var line_a = "" +for i in [0..d[ do line_a += " " +line_a += a.to_s +line_a.draw( disp_char, disp_size, disp_gap, false ) + +print "" +# draw second line +d = max_len - len_b-1 +var line_b = op_char.to_s +for i in [0..d[ do line_b += " " +line_b += b.to_s +line_b.draw( disp_char, disp_size, disp_gap, false ) + +# draw ----- +print "" +for i in [0..disp_size*max_len+(max_len-1)*disp_gap] do + printn "_" +end +print "" +print "" + +# draw result +d = max_len - len_res +var line_res = "" +for i in [0..d[ do line_res += " " +line_res += result.to_s +line_res.draw( disp_char, disp_size, disp_gap, false ) +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net> +# +# 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. + +# Example using the privileges module to drop privileges from root +module drop_privileges + +import privileges + +# basic command line options +var opts = new OptionContext +var opt_ug = new OptionUserAndGroup.for_dropping_privileges +opt_ug.mandatory = true +opts.add_option(opt_ug) + +# parse and check command line options +opts.parse(args) +if not opts.errors.is_empty then + print opts.errors + print "Usage: drop_privileges [options]" + opts.usage + exit 1 +end + +# original user +print "before {sys.uid}:{sys.gid}" + +# make the switch +var user_group = opt_ug.value +assert user_group != null +user_group.drop_privileges + +# final user +print "after {sys.uid}:{sys.egid}" +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2012-2013 Alexis Laferrière <alexis.laf@xymus.net> +# +# 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. + +# This module illustrates some uses of the FFI, specifically +# how to use extern methods. Which means to implement a Nit method in C. +module extern_methods + +redef enum Int + # Returns self'th fibonnaci number + # implemented here in C for optimization purposes + fun fib : Int import fib `{ + if ( recv < 2 ) + return recv; + else + return Int_fib( recv-1 ) + Int_fib( recv-2 ); + `} + + # System call to sleep for "self" seconds + fun sleep `{ + sleep( recv ); + `} + + # Return atan2l( self, x ) from libmath + fun atan_with( x : Int ) : Float `{ + return atan2( recv, x ); + `} + + # This method callback to Nit methods from C code + # It will use from C code: + # * the local fib method + # * the + operator, a method of Int + # * to_s, a method of all objects + # * String.to_cstring, a method of String to return an equivalent char* + fun foo import fib, +, to_s, String.to_cstring `{ + long recv_fib = Int_fib( recv ); + long recv_plus_fib = Int__plus( recv, recv_fib ); + + String nit_string = Int_to_s( recv_plus_fib ); + char *c_string = String_to_cstring( nit_string ); + + printf( "from C: self + fib(self) = %s\n", c_string ); + `} + + # Equivalent to foo but written in pure Nit + fun bar do print "from Nit: self + fib(self) = {self+self.fib}" +end + +print 12.fib + +print "sleeping 1 second..." +1.sleep + +print 100.atan_with( 200 ) +8.foo +8.bar + +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2004-2008 Jean Privat <jean@pryen.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. + +# A simple exemple of refinement where a method is added to the integer class. +module fibonacci + +redef class Int + # Calculate the self-th element of the fibonacci sequence. + fun fibonacci: Int + do + if self < 2 then + return 1 + else + return (self-2).fibonacci + (self-1).fibonacci + end + end +end + +# Print usage and exit. +fun usage +do + print "Usage: fibonnaci <integer>" + exit 0 +end + +# Main part +if args.length != 1 then + usage +end +print args.first.to_i.fibonacci +print "hello world" +# 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. + +import html + +class NitHomepage + super HTMLPage + + redef fun head do + add("meta").attr("charset", "utf-8") + add("title").text("Nit") + add("link").attr("rel", "icon").attr("href", "http://nitlanguage.org/favicon.ico").attr("type", "image/x-icon") + add("link").attr("rel", "stylesheet").attr("href", "http://nitlanguage.org/style.css").attr("type", "text/css") + add("link").attr("rel", "stylesheet").attr("href", "http://nitlanguage.org/local.css").attr("type", "text/css") + end + + redef fun body do + open("article").add_class("page") + open("section").add_class("pageheader") + add_html("<a id='toptitle_first' class='toptitle'>the</a><a id='toptitle_second' class='toptitle' href=''>Nit</a><a id='toptitle_third' class='toptitle' href=''>Programming Language</a>") + open("header").add_class("header") + open("div").add_class("topsubtitle") + add("p").text("A Fun Language for Serious Programming") + close("div") + close("header") + close("section") + + open("div").attr("id", "pagebody") + open("section").attr("id", "content") + add("h1").text("# What is Nit?") + add("p").text("Nit is an object-oriented programming language. The goal of Nit is to propose a robust statically typed programming language where structure is not a pain.") + add("p").text("So, what does the famous hello world program look like, in Nit?") + add_html("<pre><tt><span class='normal'>print </span><span class='string'>'Hello, World!'</span></tt></pre>") + + add("h1").text("# Feature Highlights") + add("h2").text("Usability") + add("p").text("Nit's goal is to be usable by real programmers for real projects") + + open("ul") + open("li") + add("a").attr("href", "http://en.wikipedia.org/wiki/KISS_principle").text("KISS principle") + close("li") + add("li").text("Script-like language without verbosity nor cryptic statements") + add("li").text("Painless static types: static typing should help programmers") + add("li").text("Efficient development, efficient execution, efficient evolution.") + close("ul") + + add("h2").text("Robustness") + add("p").text("Nit will help you to write bug-free programs") + + open("ul") + add("li").text("Strong static typing") + add("li").text("No more NullPointerException") + close("ul") + + add("h2").text("Object-Oriented") + add("p").text("Nit's guideline is to follow the most powerful OO principles") + + open("ul") + open("li") + add("a").attr("href", "./everything_is_an_object/").text("Everything is an object") + close("li") + open("li") + add("a").attr("href", "./multiple_inheritance/").text("Multiple inheritance") + close("li") + open("li") + add("a").attr("href", "./refinement/").text("Open classes") + close("li") + open("li") + add("a").attr("href", "./virtual_types/").text("Virtual types") + close("li") + close("ul") + + + add("h1").text("# Getting Started") + add("p").text("Get Nit from its Git repository:") + + add_html("<pre><code>$ git clone http://nitlanguage.org/nit.git</code></pre>") + add("p").text("Build the compiler (may be long):") + add_html("<pre><code>$ cd nit\n") + add_html("$ make</code></pre>") + add("p").text("Compile a program:") + add_html("<pre><code>$ bin/nitc examples/hello_world.nit</code></pre>") + add("p").text("Execute the program:") + add_html("<pre><code>$ ./hello_world</code></pre>") + close("section") + close("div") + close("article") + end +end + +var page = new NitHomepage +page.write_to stdout +page.write_to_file("nit.html") +# 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. + +# An example that defines and uses stacks of integers. +# The implementation is done with a simple linked list. +# It features: free constructors, nullable types and some adaptive typing. +module int_stack + +# A stack of integer implemented by a simple linked list. +# Note that this is only a toy class since a real linked list will gain to use +# generics and extends interfaces, like Collection, from the standard library. +class IntStack + # The head node of the list. + # Null means that the stack is empty. + private var head: nullable ISNode = null + + # Add a new integer in the stack. + fun push(val: Int) + do + self.head = new ISNode(val, self.head) + end + + # Remove and return the last pushed integer. + # Return null if the stack is empty. + fun pop: nullable Int + do + var head = self.head + if head == null then return null + # Note: the followings are statically safe because of the + # previous 'if'. + var val = head.val + self.head = head.next + return val + end + + # Return the sum of all integers of the stack. + # Return 0 if the stack is empty. + fun sumall: Int + do + var sum = 0 + var cur = self.head + while cur != null do + # Note: the followings are statically safe because of + # the condition of the 'while'. + sum += cur.val + cur = cur.next + end + return sum + end + + # Note: Because all attributes have a default value, a free constructor + # "init()" is implicitly defined. +end + +# A node of a IntStack +private class ISNode + # The integer value stored in the node. + var val: Int + + # The next node, if any. + var next: nullable ISNode + + # Note: A free constructor "init(val: Int, next: nullable ISNode)" is + # implicitly defined. +end + +var l = new IntStack +l.push(1) +l.push(2) +l.push(3) + +print l.sumall + +# Note: the 'for' control structure cannot be used on IntStack in its current state. +# It requires a more advanced topic. +# However, why not using the 'loop' control structure? +loop + var i = l.pop + if i == null then break + # The following is statically safe because of the previous 'if'. + print i * 10 +end + +# Note: 'or else' is used to give an alternative of a null expression. +l.push(5) +print l.pop or else 0 # l.pop gives 5, so print 5 +print l.pop or else 0 # l.pop gives null, so print the alternative: 0 + + +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net> +# +# 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. + +# Basic example of OpenGL ES 2.0 usage from the book OpenGL ES 2.0 Programming Guide. +# +# Code reference: +# https://code.google.com/p/opengles-book-samples/source/browse/trunk/LinuxX11/Chapter_2/Hello_Triangle/Hello_Triangle.c +module opengles2_hello_triangle + +import glesv2 +import egl +import mnit_linux # for sdl +import x11 + +if "NIT_TESTING".environ == "true" then exit(0) + +var window_width = 800 +var window_height = 600 + +# +## SDL +# +var sdl_display = new SDLDisplay(window_width, window_height) +var sdl_wm_info = new SDLSystemWindowManagerInfo +var x11_window_handle = sdl_wm_info.x11_window_handle + +# +## X11 +# +var x_display = x_open_default_display +assert x_display != 0 else print "x11 fail" + +# +## EGL +# +var egl_display = new EGLDisplay(x_display) +assert egl_display.is_valid else print "EGL display is not valid" +egl_display.initialize + +print "EGL version: {egl_display.version}" +print "EGL vendor: {egl_display.vendor}" +print "EGL extensions: {egl_display.extensions.join(", ")}" +print "EGL client APIs: {egl_display.client_apis.join(", ")}" + +assert egl_display.is_valid else print egl_display.error + +var config_chooser = new EGLConfigChooser +#config_chooser.surface_type_egl +config_chooser.blue_size = 8 +config_chooser.green_size = 8 +config_chooser.red_size = 8 +#config_chooser.alpha_size = 8 +#config_chooser.depth_size = 8 +#config_chooser.stencil_size = 8 +#config_chooser.sample_buffers = 1 +config_chooser.close + +var configs = config_chooser.choose(egl_display) +assert configs != null else print "choosing config failed: {egl_display.error}" +assert not configs.is_empty else print "no EGL config" + +print "{configs.length} EGL configs available" +for config in configs do + var attribs = config.attribs(egl_display) + print "* caveats: {attribs.caveat}" + print " conformant to: {attribs.conformant}" + print " size of RGBA: {attribs.red_size} {attribs.green_size} {attribs.blue_size} {attribs.alpha_size}" + print " buffer, depth, stencil: {attribs.buffer_size} {attribs.depth_size} {attribs.stencil_size}" +end + +var config = configs.first + +var format = config.attribs(egl_display).native_visual_id + +# TODO android part +# Opengles1Display_midway_init(recv, format); + +var surface = egl_display.create_window_surface(config, x11_window_handle, [0]) +assert surface.is_ok else print egl_display.error + +var context = egl_display.create_context(config) +assert context.is_ok else print egl_display.error + +var make_current_res = egl_display.make_current(surface, surface, context) +assert make_current_res + +var width = surface.attribs(egl_display).width +var height = surface.attribs(egl_display).height +print "Width: {width}" +print "Height: {height}" + +assert egl_bind_opengl_es_api else print "eglBingAPI failed: {egl_display.error}" + +# +## GLESv2 +# + +print "Can compile shaders? {gl_shader_compiler}" +assert_no_gl_error + +assert gl_shader_compiler else print "Cannot compile shaders" + +# gl program +print gl_error.to_s +var program = new GLProgram +if not program.is_ok then + print "Program is not ok: {gl_error.to_s}\nLog:" + print program.info_log + abort +end +assert_no_gl_error + +# vertex shader +var vertex_shader = new GLVertexShader +assert vertex_shader.is_ok else print "Vertex shader is not ok: {gl_error}" +vertex_shader.source = """ +attribute vec4 vPosition; +void main() +{ + gl_Position = vPosition; +} """ +vertex_shader.compile +assert vertex_shader.is_compiled else print "Vertex shader compilation failed with: {vertex_shader.info_log} {program.info_log}" +assert_no_gl_error + +# fragment shader +var fragment_shader = new GLFragmentShader +assert fragment_shader.is_ok else print "Fragment shader is not ok: {gl_error}" +fragment_shader.source = """ +precision mediump float; +void main() +{ + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); +} +""" +fragment_shader.compile +assert fragment_shader.is_compiled else print "Fragment shader compilation failed with: {fragment_shader.info_log}" +assert_no_gl_error + +program.attach_shader vertex_shader +program.attach_shader fragment_shader +program.bind_attrib_location(0, "vPosition") +program.link +assert program.is_linked else print "Linking failed: {program.info_log}" +assert_no_gl_error + +# draw! +var vertices = [0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0] +var vertex_array = new VertexArray(0, 3, vertices) +vertex_array.attrib_pointer +gl_clear_color(0.5, 0.0, 0.5, 1.0) +for i in [0..10000[ do + printn "." + assert_no_gl_error + gl_viewport(0, 0, width, height) + gl_clear_color_buffer + program.use + vertex_array.enable + vertex_array.draw_arrays_triangles + egl_display.swap_buffers(surface) +end + +# delete +program.delete +vertex_shader.delete +fragment_shader.delete + +# +## EGL +# +# close +egl_display.make_current(new EGLSurface.none, new EGLSurface.none, new EGLContext.none) +egl_display.destroy_context(context) +egl_display.destroy_surface(surface) + +# +## SDL +# +# close +sdl_display.destroy +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2004-2008 Jean Privat <jean@pryen.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. + +# How to print arguments of the command line. +module print_arguments + +for a in args do + print a +end +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2004-2008 Jean Privat <jean@pryen.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. + +# A procedural program (without explicit class definition). +# This program manipulates arrays of integers. +module procedural_array + +# The sum of the elements of `a'. +# Uses a 'for' control structure. +fun array_sum(a: Array[Int]): Int +do + var sum = 0 + for i in a do + sum = sum + i + end + return sum +end + +# The sum of the elements of `a' (alternative version). +# Uses a 'while' control structure. +fun array_sum_alt(a: Array[Int]): Int +do + var sum = 0 + var i = 0 + while i < a.length do + sum = sum + a[i] + i = i + 1 + end + return sum +end + +# The main part of the program. +var a = [10, 5, 8, 9] +print(array_sum(a)) +print(array_sum_alt(a)) +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> +# +# 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. + +# Client sample using the Socket module which connect to the server sample. +module socket_client + +import socket + +if args.length < 2 then + print "Usage : socket_client <host> <port>" + return +end + +var s = new Socket.client(args[0], args[1].to_i) +print "[HOST ADDRESS] : {s.address}" +print "[HOST] : {s.host}" +print "[PORT] : {s.port}" +print "Connecting ... {s.connected}" +if s.connected then + print "Writing ... Hello server !" + s.write("Hello server !") + print "[Response from server] : {s.read(100)}" + print "Closing ..." + s.close +end +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2013 Matthieu Lucas <lucasmatthieu@gmail.com> +# +# 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. + +# Server sample using the Socket module which allow client to connect +module socket_server + +import socket + +if args.is_empty then + print "Usage : socket_server <port>" + return +end + +var socket = new Socket.server(args[0].to_i, 1) +print "[PORT] : {socket.port.to_s}" + +var clients = new Array[Socket] +var max = socket +loop + var fs = new SocketObserver(true, true, true) + fs.readset.set(socket) + + for c in clients do fs.readset.set(c) + + if fs.select(max, 4, 0) == 0 then + print "Error occured in select {sys.errno.strerror}" + break + end + + if fs.readset.is_set(socket) then + var ns = socket.accept + print "Accepting {ns.address} ... " + print "[Message from {ns.address}] : {ns.read(100)}" + ns.write("Goodbye client.") + print "Closing {ns.address} ..." + ns.close + end +end + +# 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. + +import template + +### Here, definition of the specific templates + +# The root template for composers +class TmplComposers + super Template + + # Short list of composers + var composers = new Array[TmplComposer] + + # Detailled list of composers + var composer_details = new Array[TmplComposerDetail] + + # Add a composer in both lists + fun add_composer(firstname, lastname: String, birth, death: Int) + do + composers.add(new TmplComposer(lastname)) + composer_details.add(new TmplComposerDetail(firstname, lastname, birth, death)) + end + + redef fun rendering do + add """ +COMPOSERS +========= +""" + add_all composers + add """ + +DETAILS +======= +""" + add_all composer_details + end +end + +# A composer in the short list of composers +class TmplComposer + super Template + + # Short name + var name: String + + init(name: String) do self.name = name + + redef fun rendering do add "- {name}\n" +end + +# A composer in the detailled list of composers +class TmplComposerDetail + super Template + + var firstname: String + var lastname: String + var birth: Int + var death: Int + + init(firstname, lastname: String, birth, death: Int) do + self.firstname = firstname + self.lastname = lastname + self.birth = birth + self.death = death + end + + redef fun rendering do add """ + +COMPOSER: {{{firstname}}} {{{lastname}}} +BIRTH...: {{{birth}}} +DEATH...: {{{death}}} +""" + +end + +### Here a simple usage of the templates + +var f = new TmplComposers +f.add_composer("Johann Sebastian", "Bach", 1685, 1750) +f.add_composer("George Frideric", "Handel", 1685, 1759) +f.add_composer("Wolfgang Amadeus", "Mozart", 1756, 1791) +f.write_to(stdout) +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2014 Lucas Bajolet <r4pass@hotmail.com> +# +# 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. + +# Sample module for a minimal chat server using Websockets on port 8088 +module websocket_server + +import websocket + +var sock = new WebSocket(8088, 1) + +var msg: String + +if sock.listener.eof then + print sys.errno.strerror +end + +sock.accept + +while not sock.listener.eof do + if not sock.connected then sock.accept + if sys.stdin.poll_in then + msg = gets + printn "Received message : {msg}" + if msg == "exit" then sock.close + if msg == "disconnect" then sock.disconnect_client + sock.write(msg) + end + if sock.can_read(10) then + msg = sock.read_line + if msg != "" then print msg + end +end + diff --git a/tests/examplefiles/example.golo b/tests/examplefiles/example.golo new file mode 100644 index 00000000..92ff78b5 --- /dev/null +++ b/tests/examplefiles/example.golo @@ -0,0 +1,113 @@ +# +# Comments +# + +module pygments.Example + +import some.Module + +local function foo = |a, b| -> a + b + +---- +golodoc string +---- +augment java.util.Collection { + + ---- + sub doc + ---- + function plop = |this, v| { + return this: length() + v + } +} + +function bar = |a, b| { + let msg = "a string" + var tmp = "" + tmp = tmp + a: toString() + println(tmp + b) +} + +function baz = { + foreach i in range(0, 5) { + if i % 2 == 0 and true or false { + print("e") + } else { + print("o") + } + } +} + +function userMatch = |v| -> + match { + when v % 2 == 0 then "e" + otherwise "o" + } +} + +function add = |x| -> |y| -> x + y + +let aChar = 'a' + +let multiline = +""" +foo +bar +baz +""" + +local function myObj = -> DynamicObject(): + name("foo"): + age(25): + define("meth", |this| -> this: name() + this: age() + +---- +Golo doc string +---- +function nullTest = { + let m = map[ + ["a", 1], + ["b", 2] + ] + + println(map: get("a") orIfNull 0) + println(map: get("b")?: toString() orIfNull "0") + +} + +struct Point = { x, y } + +function deco1 = |fun| { + return |args...| { + return "deco1 + " + fun: invokeWithArguments(args) + } +} + +@deco1 +function decofoo = |a| { + return "foo: " + a +} + +@deco1 +function decobar = |a| -> "bar: " + a + +function deco2 = |fun| { + return |args...| { + return "deco2 + " + fun: invokeWithArguments(args) + } +} + +@deco2 +@deco1 +function decobaz = |a| -> "baz: " + a + +let deco3 = ^deco1: andThen(^deco2) + +@deco3 +function decospam = |a| -> "spam: " + a + +@another.Module.deco +function ping = -> "pong" + +@deco("with", params) +function gnop = -> "gnip" diff --git a/tests/examplefiles/example_elixir.ex b/tests/examplefiles/example_elixir.ex index 0912d099..ddca7f60 100644 --- a/tests/examplefiles/example_elixir.ex +++ b/tests/examplefiles/example_elixir.ex @@ -1,13 +1,19 @@ # Numbers 0b0101011 -1234 ; 0x1A ; 0xbeef ; 0763 +1234 ; 0x1A ; 0xbeef ; 0763 ; 0o123 3.14 ; 5.0e21 ; 0.5e-12 100_000_000 +# these are not valid numbers +0b012 ; 0xboar ; 0o888 +0B01 ; 0XAF ; 0O123 + # Characters ?a ; ?1 ; ?\n ; ?\s ; ?\c ; ? ; ?, ?\x{12} ; ?\x{abcd} -?\x34 ; ?\xf +?\x34 ; ?\xF + +# these show that only the first digit is part of the character ?\123 ; ?\12 ; ?\7 # Atoms @@ -18,12 +24,13 @@ line ' \s \123 \xff atom" :... ; :<<>> ; :%{} ; :% ; :{} -:++; :--; :*; :~~~ +:++; :--; :*; :~~~; ::: +:% ; :. ; :<- # Strings "Hello world" -"Interspersed \x{ff} codes \7 \8 \65 \016 and \t\s\z\+ \\ escapes" -"Quotes ' inside \" \123 the \"\" \xF string \\\" end" +"Interspersed \x{ff} codes \7 \8 \65 \016 and \t\s\\s\z\+ \\ escapes" +"Quotes ' inside \" \123 the \"\" \xF \\xF string \\\" end" "Multiline string" @@ -45,18 +52,28 @@ atom" ~w(hello #{ ["has" <> "123", '\c\d', "\123 interpol" | []] } world)s ~W(hello #{no "123" \c\d \123 interpol} world)s +~s{Escapes terminators \{ and \}, but no {balancing} # outside of sigil here } + ~S"No escapes \s\t\n and no #{interpolation}" :"atoms work #{"to" <> "o"}" # Operators x = 1 + 2.0 * 3 -y = true and false; z = false xor true +y = true and false; z = false or true ... = 144 ... == !x && y || z "hello" |> String.upcase |> String.downcase() {^z, a} = {true, x} +# Free operators (added in 1.0.0) +p ~>> f = bind(p, f) +p1 ~> p2 = pair_right(p1, p2) +p1 <~ p2 = pair_left(p1, p2) +p1 <~> p2 = pair_both(p1, p2) +p |~> f = map(p, f) +p1 <|> p2 = either(p1, p2) + # Lists, tuples, maps, keywords [1, :a, 'hello'] ++ [2, 3] [:head | [?t, ?a, ?i, ?l]] @@ -75,13 +92,18 @@ map = %{shortcut: "syntax"} # Comprehensions for x <- 1..10, x < 5, do: {x, x} pixels = "12345678" -for << <<r::4, g::4, b::4, a::4>> <- pixels >> do +for << <<r::4, g::4, b::4, a::size(4)>> <- pixels >> do [r, {g, %{"b" => a}}] end # String interpolation "String #{inspect "interpolation"} is quite #{1+4+7} difficult" +# Identifiers +abc_123 = 1 +_018OP = 2 +A__0 == 3 + # Modules defmodule Long.Module.Name do @moduledoc "Simple module docstring" @@ -89,7 +111,12 @@ defmodule Long.Module.Name do @doc """ Multiline docstring "with quotes" - and #{ %{"interpolation" => "in" <> "action"} } + and #{ inspect %{"interpolation" => "in" <> "action"} } + now with #{ {:a, 'tuple'} } + and #{ inspect { + :tuple, + %{ with: "nested #{ inspect %{ :interpolation => %{} } }" } + } } """ defstruct [:a, :name, :height] @@ -110,7 +137,8 @@ end # Structs defmodule Second.Module do s = %Long.Module.Name{name: "Silly"} - %{s | height: {192, :cm}} + %Long.Module.Name{s | height: {192, :cm}} + ".. #{%Long.Module.Name{s | height: {192, :cm}}} .." end # Types, pseudo-vars, attributes @@ -182,7 +210,7 @@ end # Lexical scope modifiers import Kernel, except: [spawn: 1, +: 2, /: 2, Unless: 2] -alias Long.Module.Name, as: Namen +alias Long.Module.Name, as: N0men123_and4 use Bitwise 4 &&& 5 diff --git a/tests/examplefiles/rust_example.rs b/tests/examplefiles/rust_example.rs index 1c0a70c3..8ffbaf6b 100644 --- a/tests/examplefiles/rust_example.rs +++ b/tests/examplefiles/rust_example.rs @@ -11,6 +11,8 @@ // based on: // http://shootout.alioth.debian.org/u32/benchmark.php?test=nbody&lang=java +/* nest some /* comments */ */ + extern mod std; use core::os; diff --git a/tests/examplefiles/test.idr b/tests/examplefiles/test.idr index f0e96d88..fd008d31 100644 --- a/tests/examplefiles/test.idr +++ b/tests/examplefiles/test.idr @@ -60,6 +60,7 @@ using (G : Vect n Ty) fromInteger = Val . fromInteger + ||| Evaluates an expression in the given context. interp : Env G -> {static} Expr G t -> interpTy t interp env (Var i) = lookup i env interp env (Val x) = x @@ -87,6 +88,13 @@ using (G : Vect n Ty) testFac : Int testFac = interp [] eFac 4 +--testFacTooBig : Int +--testFacTooBig = interp [] eFac 100000 + + {-testFacTooBig2 : Int +testFacTooBig2 = interp [] eFac 1000 +-} + main : IO () main = print testFac |