Skip to content

Commit

Permalink
* comparison with empty string and empty list is now fast
Browse files Browse the repository at this point in the history
* comparison with data-less variant case is also fast (just tag comparison)
* introduced intrinsic math functions
* can not omit () around {} in pattern matching, e.g. CVal, KVal in the compiler.
  • Loading branch information
vpisarev committed Mar 27, 2021
1 parent 6c59e7e commit 6d1ed6a
Show file tree
Hide file tree
Showing 22 changed files with 303 additions and 142 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,23 @@ The code is distributed under Apache 2 license, see the [LICENSE](LICENSE)

## How to build

The compiler has been written in Ficus itself and needs C/C++ compiler and make utility.
The compiler is written in Ficus itself and needs C/C++ compiler and make utility.

```
cd <ficus_root>
make
FICUS_PATH=./lib FICUS_CFLAGS=-I./runtime ./ficus -run -O3 examples/fst.fx
# or
# ./ficus -I ./lib -cflags "-I./runtime" -run -O3 examples/fst.fx
```

`FICUS_PATH` and `FICUS_CFLAGS` are the two variables to setup to make ficus usable from any directory.

* The first one, `FICUS_PATH`, should be set to the path to the standard library (`<ficus_root>/lib`), but also can contain
other paths separated by `:` on Unix and `;` on Windows. Note that if a compiled module imports other modules
* The first one, `FICUS_PATH`, should point to the standard library (`<ficus_root>/lib`), but can also contain
other directories separated by `:` on Unix and `;` on Windows. Note that if a compiled module imports other modules
from the directory where it resides, that directory does not need to be included.

* The second one, `FICUS_CFLAGS`, is passed to C/C++ compiler to build the produced .c/.cpp files.
* The second one, `FICUS_CFLAGS`, is used by C/C++ compiler to build the produced .c/.cpp files.
The generated files include ficus runtime headers, and the path to the runtime directory needs
to be specified via command line option `-cflags` or the environment variable.

Expand Down
31 changes: 30 additions & 1 deletion compiler/Ast.fx
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@ type binary_t = OpAdd | OpSub | OpMul | OpDiv | OpMod | OpPow
type unary_t = OpPlus | OpNegate | OpDotMinus | OpBitwiseNot | OpLogicNot
| OpMkRef | OpDeref | OpExpand | OpApos

type intrin_t =
| IntrinPopExn
| IntrinVariantTag
| IntrinVariantCase
| IntrinListHead
| IntrinListTail
| IntrinStrConcat
| IntrinGetSize
| IntrinCheckIdx
| IntrinCheckIdxRange
| IntrinMath: id_t

type val_flags_t =
{
val_flag_arg: bool = false;
Expand Down Expand Up @@ -267,6 +279,7 @@ type exp_t =
| ExpIdent: (id_t, ctx_t)
| ExpBinary: (binary_t, exp_t, exp_t, ctx_t)
| ExpUnary: (unary_t, exp_t, ctx_t)
| ExpIntrin: (intrin_t, exp_t list, ctx_t)
| ExpSeq: (exp_t list, ctx_t)
| ExpMkTuple: (exp_t list, ctx_t)
| ExpMkArray: (exp_t list list, ctx_t)
Expand Down Expand Up @@ -618,6 +631,7 @@ fun get_exp_ctx(e: exp_t) {
| ExpIdent(_, c) => c
| ExpBinary(_, _, _, c) => c
| ExpUnary(_, _, c) => c
| ExpIntrin(_, _, c) => c
| ExpSeq(_, c) => c
| ExpMkTuple(_, c) => c
| ExpMkRecord(_, _, c) => c
Expand Down Expand Up @@ -956,6 +970,20 @@ fun string(uop: unary_t) {
| OpApos => "'"
}

fun string(iop: intrin_t): string
{
| IntrinPopExn => "__intrin_pop_exn__"
| IntrinVariantTag => "__intrin_variant_tag__"
| IntrinVariantCase => "__intrin_variant_case__"
| IntrinListHead => "__intrin_hd__"
| IntrinListTail => "__intrin_tl__"
| IntrinStrConcat => "__intrin_str_concat__"
| IntrinGetSize => "__intrin_size__"
| IntrinCheckIdx => "__intrin_check_idx__"
| IntrinCheckIdxRange => "__intrin_check_range__"
| IntrinMath(f) => f"__intrin_{pp(f)}__"
}

fun border2str(border: border_t, f: bool) {
val pt = if f {"."} else {""}
match border {
Expand Down Expand Up @@ -1333,6 +1361,7 @@ fun walk_exp(e: exp_t, callb: ast_callb_t) {
| ExpIdent(n, ctx) => ExpIdent(n, walk_ctx_(ctx))
| ExpBinary(bop, e1, e2, ctx) => ExpBinary(bop, walk_exp_(e1), walk_exp_(e2), walk_ctx_(ctx))
| ExpUnary(uop, e, ctx) => ExpUnary(uop, walk_exp_(e), walk_ctx_(ctx))
| ExpIntrin(iop, args, ctx) => ExpIntrin(iop, walk_elist_(args), walk_ctx_(ctx))
| ExpSeq(elist, ctx) => ExpSeq(walk_elist_(elist), walk_ctx_(ctx))
| ExpMkTuple(elist, ctx) => ExpMkTuple(walk_elist_(elist), walk_ctx_(ctx))
| ExpMkArray(ell, ctx) => ExpMkArray([: for el <- ell {walk_elist_(el)} :], walk_ctx_(ctx))
Expand All @@ -1358,7 +1387,7 @@ fun walk_exp(e: exp_t, callb: ast_callb_t) {
| ExpCCode(str, ctx) => ExpCCode(str, walk_ctx_(ctx))
| DefVal(p, v, flags, loc) => DefVal(walk_pat_(p), walk_exp_(v), flags, loc)
| DefFun(df) =>
if !df->df_templ_args.empty() {
if df->df_templ_args != [] {
e
} else {
val {df_args, df_typ, df_body} = *df
Expand Down
11 changes: 9 additions & 2 deletions compiler/Ast_pp.fx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fun pprint_val_flags(pp: PP.t, flags: val_flags_t): void
if flags.val_flag_temp { pp.str("@temp"); pp.space() }
if flags.val_flag_private { pp.str("@private"); pp.space() }
if flags.val_flag_subarray { pp.str("@subarray"); pp.space() }
if !flags.val_flag_global.empty() { pp.str("@global"); pp.space() }
if flags.val_flag_global != [] { pp.str("@global"); pp.space() }
if flags.val_flag_arg { pp.str("@arg"); pp.space() }
}

Expand Down Expand Up @@ -248,7 +248,7 @@ fun pprint_exp(pp: PP.t, e: exp_t): void
}
pp.space(); ppid(pp, dvar_name);
pp.str(" ="); pp.space()
val ctors = if !dvar_ctors.empty() { dvar_ctors } else { [: for (n, t) <- dvar_cases {n} :] }
val ctors = if dvar_ctors != [] { dvar_ctors } else { [: for (n, t) <- dvar_cases {n} :] }
for (_, t)@i <- dvar_cases, c <- ctors {
pp.begin(); pp.str("| ");
ppid(pp, c); pp.str(": "); pp.space();
Expand Down Expand Up @@ -340,6 +340,13 @@ fun pprint_exp(pp: PP.t, e: exp_t): void
| ExpUnary(o, e1, _) =>
pp.str("("); pp.str(f"{o}");
pp.space(); ppexp(e1); pp.str(")")
| ExpIntrin(i, args, _) =>
pp.str(string(i)); pp.str("(")
for e@i <- args {
if i > 0 { pp.str(","); pp.space() }
ppexp(e)
}
pp.str(")")
| ExpThrow(e1, _) =>
pp.str("throw"); pp.space(); ppexp(e1)
| ExpMkTuple(el, _) =>
Expand Down
Loading

0 comments on commit 6d1ed6a

Please sign in to comment.