vpisarev / ficus Goto Github PK
View Code? Open in Web Editor NEWThe programming language Ficus
License: Apache License 2.0
The programming language Ficus
License: Apache License 2.0
right now the standard library, module Re
, offers 2 functions:
Re.compile(regexp_str: string) : Re.regex_t
andRe.match_(regexp_obj: Re.regex_t, matched_str: string): bool
The implementation uses Rob Pike's VM approach (O(N) regexp matching algorithm, where N is the matched string length), described and implemented at https://swtch.com/~rsc/regexp/; in particular, it's a wrapper on top of re1
library.
The implementation is just at "technology preview" level of functionality and stability. Here is the list of things to make this module really useful:
freesub
). It should be possible to invoke the regexp engine simultaneously from multiple threads (using different compiled regexp objects or even the same regexp).sub[0] == 0 && sub[1] == str_length
.Re.match_(r: Re.regex_t, s: string): (bool, (int, int)[])
. That is, in addition to the success flag, return positions of submatches as 1D array of 2-element tuples (start_j, end_j)
. (start_0, end_0)
โ position of the whole regexp within the searched string. Remember that int
in Ficus corresponds to int_ ~ ptrdiff_t
in C.r"regexp_str"
to Ficus to automatically mirror back slashes.s ~ regexp
syntax to Ficus (syntactic sugar): if input_filename ~ "{basename:.+}\.fx" { println(f"base name of the ficus source file is {basename}") }
. That is, regexp matching, as in Perl, can be an operator with optional value capture. If matching is successful, we can get the named captured values and use them.Re.find(regexp_obj: Re.regex_t, str: string): (bool, (int, int) [])
. The semantics matches Re.match_()
, but the match can be a substring of str
, instead of the whole str
. Maybe there should be overloaded version that will take extra offset: int
parameter โ from where to start the search.Re.findall(regexp_obj: Re.regex_t, str: string): (int, int) [,]
. Returns matrix. i-th row corresponds to i-th match and contains the position of the whole match and positions of sub-matches.Re.replace(regexp_obj: Re.regexp_t, str: str: string, replace_with: string): string
. replace_with
string can use \<n>
syntax, e.g. \0
(the whole matched string) \1
(the first matched sub-expression), \2
(the second matched sub-expression) etc.Re.replace()
functionality. \U1
will mean convert the first submatch to uppercase, \L2
will mean convert the second submatch to lowercase, \C0
will mean capitalize the whole submatch (convert the first letter of it to uppercase).[[^]c1-c2c3-c4c5-c6]
syntax for specifying positive and negative character ranges. There should be new instructions in VM to implement this. Maybe it should be a variable-length instruction FX_RE_OP_POSRANGE
and FX_RE_OP_NEGRANGE
. Single characters can be encoded (internally) by duplicating the beginning and end of the range, e.g. [+-0-9]
can be encoded as [+-+\--\-0-9]
.\b
- word boundary. There should probably be a new VM instruction (like FX_RE_OP_WORDBOUND
) to implement it.\t
, \r
, \n
, \x..
, \u....
, \U........
syntax to specify various characters.\s
(space), \d
(decimal digit), \x
(hexadecimal digit), \a
(letter), \w
(letter, decimal digit or underscore), and maybe some others. fx_isdigit()
and other standard functions from ficus runtime can be used to implement this part, and probably a new VM instruction (e.g. FX_RE_OP_CHARCLASS <class_id>
) should take care of it.^
(beginning-of-line) anchor (FX_RE_OP_BEGIN_OF_LINE
)$
(end-of-line) anchor (FX_RE_END_OF_LINE
).Re.matchsome(rl: Re.regex_t list, str: string[, offset: int]): (int, (int, int) [])
. That is, we check if str
or str[offset:]
matches with any of regexp from rl
. If there are several matches, the longest is chosen. If there are several matches of the same length, the earliest expression in the list is chosen. The index of matched expression is returned. Such functionality can be useful to implement parsers (but using lex should be much more efficient in general for such tasks).Re.match*()
, Re.find*()
and Re.replace()
. The most important flags are ignore-case
and multi-line matches
. Need to double-check if it's consistent with other regexp engines. In the case of multi-line matches .
or \s
can match \r
or \n
or \r\n
, ^
can match beginning of each line, $
- the end of each line.=======
IMPORTANT NOTE:
It's a lot of work to bring the current very early draft to a solid state, even though many of the items are relatively easy to implement. Probably, instead of trying to make re1
-based engine more mature, it makes sense to write a ficus wrapper on top of re2, implemented in C++, where all of the above features (and probably more) are already implemented.
this is not a high-priority item at all, but maybe it would be nice to add a true 'decimal' floating-point number type to ficus, based on https://github.com/vpisarev/DEC64/tree/alt.
The rationale:
The details:
templ() and test_templ() in test/fst.fx example demonstrate the problem:
fun templ(x: 't): 't = x + (i :> 't)
fun test_templ()
{
val i = 5
templ(7.0)
}
the correct behaviour would be to report error about missing i.
(in bold there are higher-priority items)
long
or bigint
or decimal
(bindings to GMP?) (libBF by Fabrice Bellard? or big.js?). See also #12... found during conversion of the compiler to ficus:
<some variant constructor>(_)
pattern should work for any number of formal parameters.NOTE: the previous big ticket was renamed and closed.
Now we have some more things to be done to finally release Ficus 1.0 (or at least Ficus 1.0 beta):
__init__.fx
in each ficus module directory (including subdirectories)pragma "framework:<framework>"
to link Apple frameworks easily without using -clibs
flag.pragma "pkg:<pkg>"
to link packages via pkg-config more easily without using -cflags
and -clibs
SomeCase: {...}
, there should be automatically introduced SomeCase.t
as type for the attribute record. Or some other way to pack and move data for the particular case.string()
and print()
with complete support for Python 3 format.return
is properly implemented, maybe notparallel for
& @sync
. What about tasks and asynchronous execution?This is the list of features to be implemented before ficus 1.0. Some of the features are optional and marked as such.
for a@index <- A
, i.e. the notation to get indices of the array element elements, not just their values. index
is a tuple in the case of multi-dimensional arrays.(...)
notation in generic function argument types to denote that the particular argument should be a tuple, but its size can be an arbitrary (for each specific size and each specific set of tuple element types a separate instance of generic function is created). There is a similar notation for records: {...}
'typ [+]
notation to denote array arguments of varying dimensionality. For each specific dimensionality a separate instance is created.[\A; \B]
, i.. use of \array
notation for compound array initialization. [\A1; \A2; ... ; \An]
denotes "vertical" concatenation of arrays, where rows of \Ai
are put next to each other. [\A1, \A2, ..., \An]
denotes horizontal concatenation, where columns of \Ai
are put next to each other. There can also be a mixed combination, and also it's possible to put scalar elements."a" + "b" + "c" + "d" + ...
as (("a" + "b") + "c") + "d" ...
, which results in multiple memory allocations and super-linear complexity, the compiler computes the final concatenation with a single call of intrinsic function.when
keyword in the patten matching to add custom predicates.match
expression with a single action, e.g. match s { | "a" | "b" => foo() | _ => bar() }
. Currently, when using multiple cases, it's not possible to capture values, but this is a minor inconvenience.object types
that will let users write lst.rev()
instead of List.rev(lst)
etc. This is very light-weight method to introduce object-oriented notation, even for very basic, intrinsic types.str[.-n]
syntax, i.e. unary minus with preceding dot. It helps to conveniently access the last string character, the last element of array etc.fun foo (a: t1, b: t2, ~param3:t3=defval3)
notation for named/optional parameters.[unzip for ...]
notation to produce a tuple of arrays as the result of comprehension instead of a single array of tuples.print()
and string()
for any typeimg.clip[y,x]
, img.zero[y,x]
or similar notation.==== some extra items ====
finally
clause into try-catch
to close files & sockets, unlock mutexes etc. safely. Shall we also add Python-like with
expression?`expr`
that expands to (expr, expr-captured-as-string, modulename, line)
. The feature will help to make assert's much more informative.Math....
functions, None
constructor etc.)for (k, d) <- mymap {...}
into Map.app()
, fold ... for x <- myset {...}
into Set.foldl(...)
etc. In general, if the object we iterate over is a module type, we will convert the loop body into a lambda function and depending on whether it's a list comprehension, folding or a simple loop, we convert it to map
, foldl
or app
.val myfont = @data "myfont.ttf"
None
etc.__name__
attribute.[ ... ]
to [| ... |]
, and leave [...]
to vectors. cons-based lists will stay [: ... :]
.match tokens { | (PLUS | MINUS) as op :: rest => ... }
. This will also solves the problem with when
, which is now not clear where to attach in the case of several alternatives.@parallel for
based on the task framework, so that it's always available, not only when the produced binaries are linked with OpenMP runtime. Getting rid of OpenMP dependency will also make ficus binaries more compact. Note that OpenMP-based parallel for backend is also possible.-pp
flag that will run .fx code through cpp
preprocessor. In addition, there should also -Dparam[=value]
command-line option to define certain macros that are passed to the preprocessorA declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.