Skip to content

Commit

Permalink
Add func lexer (#2232)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Volkov committed Sep 17, 2022
1 parent f69cddc commit fcfcdcd
Show file tree
Hide file tree
Showing 5 changed files with 634 additions and 0 deletions.
1 change: 1 addition & 0 deletions pygments/lexers/_mapping.py
Expand Up @@ -167,6 +167,7 @@
'FortranLexer': ('pygments.lexers.fortran', 'Fortran', ('fortran', 'f90'), ('*.f03', '*.f90', '*.F03', '*.F90'), ('text/x-fortran',)),
'FoxProLexer': ('pygments.lexers.foxpro', 'FoxPro', ('foxpro', 'vfp', 'clipper', 'xbase'), ('*.PRG', '*.prg'), ()),
'FreeFemLexer': ('pygments.lexers.freefem', 'Freefem', ('freefem',), ('*.edp',), ('text/x-freefem',)),
'FuncLexer': ('pygments.lexers.func', 'FunC', ('func', 'fc'), ('*.fc', '*.func'), ()),
'FutharkLexer': ('pygments.lexers.futhark', 'Futhark', ('futhark',), ('*.fut',), ('text/x-futhark',)),
'GAPConsoleLexer': ('pygments.lexers.algebra', 'GAP session', ('gap-console', 'gap-repl'), ('*.tst',), ()),
'GAPLexer': ('pygments.lexers.algebra', 'GAP', ('gap',), ('*.g', '*.gd', '*.gi', '*.gap'), ()),
Expand Down
108 changes: 108 additions & 0 deletions pygments/lexers/func.py
@@ -0,0 +1,108 @@
"""
pygments.lexers.func
~~~~~~~~~~~~~~~~~~~~
Lexers for FunC.
:copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

from pygments.lexer import RegexLexer, include, words
from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
Number, Whitespace, Punctuation

__all__ = ['FuncLexer']


class FuncLexer(RegexLexer):
"""
For FunC source code.
"""

name = 'FunC'
aliases = ['func', 'fc']
filenames = ['*.fc', '*.func']

# 1. Does not start from "
# 2. Can start from ` and end with `, containing any character
# 3. Starts with underscore or { or } and have more than 1 character after it
# 4. Starts with letter, contains letters, numbers and underscores
identifier = r'(?!")(`([^`]+)`|((?=_)_|(?=\{)\{|(?=\})\}|(?![_`{}]))([^;,\[\]\(\)\s~.]+))'

tokens = {
'root': [
(r'\n', Whitespace),
(r'\s+', Whitespace),

include('keywords'),
include('strings'),
include('directives'),
include('numeric'),
include('comments'),
include('storage'),
include('functions'),
include('variables'),

(r'[.;(),\[\]~{}]', Punctuation)
],
'keywords': [
(words((
'<=>', '>=', '<=', '!=', '==', '^>>', '~>>',
'>>', '<<', '/%', '^%', '~%', '^/', '~/', '+=',
'-=', '*=', '/=', '~/=', '^/=', '%=', '^%=', '<<=',
'>>=', '~>>=', '^>>=', '&=', '|=', '^=', '^', '=',
'~', '/', '%', '-', '*', '+','>',
'<', '&', '|', ':', '?'), prefix=r'(?<=\s)', suffix=r'(?=\s)'),
Operator),
(words((
'if', 'ifnot',
'else', 'elseif', 'elseifnot',
'while', 'do', 'until', 'repeat',
'return', 'impure', 'method_id',
'forall', 'asm', 'inline', 'inline_ref'), prefix=r'\b', suffix=r'\b'),
Keyword),
(words(('true', 'false'), prefix=r'\b', suffix=r'\b'), Keyword.Constant),
],
'directives': [
(r'#include|#pragma', Keyword, 'directive'),
],
'directive': [
include('strings'),
(r'\s+', Whitespace),
(r'version|not-version', Keyword),
(r'(>=|<=|=|>|<|\^)?([0-9]+)(.[0-9]+)?(.[0-9]+)?', Number), # version
(r';', Text, '#pop')
],
'strings': [
(r'\"([^\n\"]+)\"[Hhcusa]?', String),
],
'numeric': [
(r'\b(-?(?!_)([\d_]+|0x[\d_a-fA-F]+)|0b[1_0]+)(?<!_)(?=[\s\)\],;])', Number)
],
'comments': [
(r';;([^\n]*)', Comment.Singleline),
(r'\{-', Comment.Multiline, 'comment'),
],
'comment': [
(r'[^-}{]+', Comment.Multiline),
(r'\{-', Comment.Multiline, '#push'),
(r'-\}', Comment.Multiline, '#pop'),
(r'[-}{]', Comment.Multiline),
],
'storage': [
(words((
'var', 'int', 'slice', 'tuple',
'cell', 'builder', 'cont', '_'),
prefix=r'\b', suffix=r'(?=[\s\(\),\[\]])'),
Keyword.Type),
(words(('global', 'const'), prefix=r'\b', suffix=r'\b'), Keyword.Constant),
],
'variables': [
(identifier, Name.Variable),
],
'functions': [
# identifier followed by (
(identifier + r'(?=[\(])', Name.Function),
]
}
52 changes: 52 additions & 0 deletions tests/examplefiles/func/test.fc
@@ -0,0 +1,52 @@
#include "../";
#pragma version >=1.0.0;

global int k_const;
const int k = 1;

() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
slice cs = in_msg_full.begin_parse();
int flags = cs~load_uint(0x4_1_0);

if ((flags & 1) == true) { ;; ignore all bounced messages
return ();
}

slice sender_address = cs~load_msg_addr();

{-
{-
test - is test
-}
-}

;; Send message
var message = begin_cell()
.store_uint(0x18, 6)
.store_slice(sender_address)
.store_coins(0)
.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
.store_slice("Hello, world!"s)
.end_cell();

send_raw_message(message, 64);

;; Update counter
var cs = get_data().begin_parse();
var counter = data~load_uint(32);

store_data(
begin_cell()
.store_uint(counter + 1, 32)
.end_cell()
);
}

() recv_external(slice in_msg) impure {
throw(0xffff);
}

int counter() method_id {
var data = get_data().begin_parse();
return data~load_uint(32);
}

0 comments on commit fcfcdcd

Please sign in to comment.