Skip to content

Commit

Permalink
many changes:
Browse files Browse the repository at this point in the history
* some of the keywords are now prepended with '@'; all the words starting with '@' are now reserved for various attributes, not to pollute the common "namespace" of reserved words:
parallel -> @parallel, pure -> @pure, nothrow -> @nothrow, static -> @Private, ccode -> @ccode, object -> @object.
"inline" was removed (probably later on @inline and maybe @non_inline will be added).
@unzip was added to indicate unzipped array comprehensions (not implemented yet).
@DaTa was added as a keyword to embed datafiles into the generated .c files, e.g. `val default_font_data = @DaTa "rubik.ttf"` (but it's not implemented yet either).

* added 2 special kinds of fold loop: all & any

fold ok=true for i <- l {if !predicate(i) {break with false}; ok}  ===> all(for i <- l {predicate(i)})
fold ok=false for i <- l {if predicate(i) {break with true}; ok}  ===> any(for i <- l {predicate(i)})

later on find and find_opt will be added.

* the body of for loop (including folding and comprehensions cases) can now be a pattern-matching body:
    for month <- months { match month { July | August => rest() | _ => work() } }
    can now be replaced with
    for _ <- months { | July | August => rest() | _ => work() }
    // note that the 'month' variable is not explicitly used and thus can be replaced with '_'

* [K|C]ExpBinOp, [K|C]ExpUnOp were renamed to easier-to-type and easier-to-read read [K|C]ExpBinary and [K|C]ExpUnary, respetively.
  • Loading branch information
vpisarev committed Mar 3, 2021
1 parent f974236 commit 15cccd5
Show file tree
Hide file tree
Showing 46 changed files with 608 additions and 526 deletions.
2 changes: 1 addition & 1 deletion compiler/Ast.fx
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,7 @@ fun is_typ_numeric(t: typ_t, allow_vec_tuples: bool) =
| TypTuple(t0 :: trest) =>
if allow_vec_tuples && is_typ_numeric(t0, true) {
val t0 = deref_typ(t0)
fold all=true for t <- trest {if deref_typ(t) != t0 {break with false}; true}
all(for t <- trest {deref_typ(t) == t0})
} else { false }
| _ => false
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/AstTypeChecker.fx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ fun maybe_unify(t1: typ_t, t2: typ_t, update_refs: bool) {

fun maybe_unify_(tl1: typ_t list, tl2: typ_t list) =
tl1.length() == tl2.length() &&
(fold ok=true for t1 <- tl1, t2 <- tl2 { if !maybe_unify_(t1, t2) {break with false}; ok })
all(for t1 <- tl1, t2 <- tl2 {maybe_unify_(t1, t2)})

fun maybe_unify_(t1: typ_t, t2: typ_t): bool =
match (t1, t2) {
Expand Down Expand Up @@ -175,7 +175,7 @@ fun maybe_unify(t1: typ_t, t2: typ_t, update_refs: bool) {
| (TypVar (ref Some(TypVarTuple(_))), TypVar (ref Some(t2_))) => maybe_unify_(t2_, t1)
| (TypVar (ref Some(TypVarTuple(_))), TypTuple(_)) => maybe_unify_(t2, t1)
| (TypTuple(tl1), TypVar((ref Some(TypVarTuple(t2_opt))) as r2)) =>
if (fold ok=false for t <- tl1 {if occurs(r2, t) {break with true}; ok}) { false }
if any(for t <- tl1 {occurs(r2, t)}) { false }
else {
val ok = match t2_opt {
| Some(t2_) => tl1.all(fun (t: typ_t) {maybe_unify_(t2_, t)})
Expand Down
14 changes: 7 additions & 7 deletions compiler/Parser.fx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ fun parse_atomic_exp(ts: token_t list)
| (LLIST, l1) :: rest =>
val (el, _, ts) = parse_exp_list(rest, parse_typed_exp, KwNone, RLIST, false, allow_empty=true,)
(fold mklist_e = ExpLit(LitNil, make_new_ctx(ol)) for e <- el.rev() {
ExpBinOp(OpCons, e, mklist_e, make_new_ctx(get_exp_loc(e)))
ExpBinary(OpCons, e, mklist_e, make_new_ctx(get_exp_loc(e)))
}, ts)
| t :: _ -> throw parse_err(ts, f"unxpected token '{tok2str(t).1}. An identifier, literal or expression enclosed in '( )', '[ ]' or '[: :]' brackets is expected here")
| _ -> throw parse_err(ts, f"premature end of the stream; check the parens")
Expand All @@ -148,15 +148,15 @@ fun parse_simple_exp(ts: token_t list)
// [TODO] add support for alternating patterns right into the pattern matching syntax
(match t1 {| DOT | ARROW => true | _ => false}) &&
(match t2 {| IDENT(false, _) | LITERAL(LitInt _) => true | _ => false}) =>
val e = match t1 { | ARROW => ExpUnOp(OpDeref, e, make_new_ctx(eloc)) | _ => e }
val e = match t1 { | ARROW => ExpUnary(OpDeref, e, make_new_ctx(eloc)) | _ => e }
val i = match t2 {
| IDENT(false, i) => ExpIdent(get_id(i), make_new_ctx(l2))
| LITERAL(LitInt(i)) => ExpLit(LitInt(i), (TypInt, l2))
| _ => ExpNop(l2)
}
(true, ExpMem(e, i, make_new_ctx(eloc)), rest)
| (t1, _) :: (LBRACE, l2) :: rest when (match t1 {| DOT | ARROW => true | _ => false}) =>
val e = match t1 { | ARROW => ExpUnOp(OpDeref, e, make_new_ctx(eloc)) | _ => e }
val e = match t1 { | ARROW => ExpUnary(OpDeref, e, make_new_ctx(eloc)) | _ => e }
val (_, rec_init_elems, ts) = parse_exp_list(rest, parse_typed_exp, KwMust, RBRACE, allow_empty=true)
(true, ExpUpdateRecord(e, rec_init_elems, make_new_ctx(eloc)), rest)
| _ => (false, e, ts)
Expand All @@ -170,10 +170,10 @@ fun parse_deref_exp(ts: token_t list)
{
| (STAR(true), l1) :: rest =>
val (e, ts) = parse_deref_exp(rest)
(ExpUnOp(OpDeref, e, make_new_ctx(l1)), ts)
(ExpUnary(OpDeref, e, make_new_ctx(l1)), ts)
| (POWER(true), l1) :: rest =>
val (e, ts) = parse_deref_exp(rest)
(ExnUnOp(OpDerf, ExpUnOp(OpDeref, e, make_new_ctx(l1)), make_new_ctx(l1)), ts)
(ExnUnOp(OpDerf, ExpUnary(OpDeref, e, make_new_ctx(l1)), make_new_ctx(l1)), ts)
| _ =>
parse_simple_exp(ts)
}
Expand All @@ -182,7 +182,7 @@ fun parse_apos_exp(ts: token_t list)
{
val (ts, e) = parse_deref_exp(ts)
match ts {
| (APOS, l1) :: rest => (ExpUnOp(OpApos, e, make_new_ctx(l1)), rest)
| (APOS, l1) :: rest => (ExpUnary(OpApos, e, make_new_ctx(l1)), rest)
| _ => (ts, e)
}
}
Expand All @@ -191,7 +191,7 @@ fun parse_unary_exp(ts: token_t list)
{
| (REF(true), l1) :: rest =>
val (e, ts) = parse_unary_exp(rest)
(ExpUnOp(OpMkRef, e, make_new_ctx ))
(ExpUnary(OpMkRef, e, make_new_ctx ))
unary_exp:
| apos_exp { $1 }
| REF unary_exp { make_un_op(OpMkRef, $2) }
Expand Down
2 changes: 1 addition & 1 deletion examples/btree.fx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ println(f"stretch tree of depth {stretch_depth}\t check: {c}")

val long_lived_tree = make(max_depth)

val report = [parallel for i <- 0 : (max_depth - min_depth) / 2 + 1
val report = [@parallel for i <- 0 : (max_depth - min_depth) / 2 + 1
{
val d = min_depth + i * 2
val niter = 1 << (max_depth - d + min_depth)
Expand Down
16 changes: 8 additions & 8 deletions examples/cpp_tree.fx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// ficus -run -O3 ../examples/cpp_tree.fx -c++
pragma "c++"

ccode //Imitation of very big included third-party library.
@ccode //Imitation of very big included third-party library.
{
#ifndef __cplusplus
#error "recompile this example with -c++ option passed to Ficus"
Expand Down Expand Up @@ -132,7 +132,7 @@ ccode //Imitation of very big included third-party library.
// Ficus interface for declared C++ terms
type eExpr_t = { handle: cptr }

fun create_eExpr(varname: string): eExpr_t = ccode
fun create_eExpr(varname: string): eExpr_t = @ccode
{
fx_cstr_t cvarname;
int stat = fx_str2cstr(varname, &cvarname, 0, 0);
Expand All @@ -144,44 +144,44 @@ fun create_eExpr(varname: string): eExpr_t = ccode
return stat;
}

fun create_eExpr(value: double): eExpr_t = ccode
fun create_eExpr(value: double): eExpr_t = @ccode
{
Number* toWrap = new Number(value);
return fx_make_cptr(toWrap, expression_free, &fx_result->handle);
}

fun to_string(expression: eExpr_t): string = ccode
fun to_string(expression: eExpr_t): string = @ccode
{
Expression* cpp_expr = (Expression*)(expression->handle->ptr);
std::string cstr = cpp_expr->printTree();
return fx_cstr2str(cstr.c_str(), cstr.size(), fx_result);
}

operator +(exp1: eExpr_t, exp2: eExpr_t): eExpr_t = ccode
operator +(exp1: eExpr_t, exp2: eExpr_t): eExpr_t = @ccode
{
Expression& cpp_expr1 = *((Expression*)(exp1->handle->ptr));
Expression& cpp_expr2 = *((Expression*)(exp2->handle->ptr));
Expression* toWrap = new Expression(cpp_expr1 + cpp_expr2);
return fx_make_cptr(toWrap, expression_free, &fx_result->handle);
}

operator -(exp1: eExpr_t, exp2: eExpr_t): eExpr_t = ccode
operator -(exp1: eExpr_t, exp2: eExpr_t): eExpr_t = @ccode
{
Expression& cpp_expr1 = *((Expression*)(exp1->handle->ptr));
Expression& cpp_expr2 = *((Expression*)(exp2->handle->ptr));
Expression* toWrap = new Expression(cpp_expr1 - cpp_expr2);
return fx_make_cptr(toWrap, expression_free, &fx_result->handle);
}

operator *(exp1: eExpr_t, exp2: eExpr_t): eExpr_t = ccode
operator *(exp1: eExpr_t, exp2: eExpr_t): eExpr_t = @ccode
{
Expression& cpp_expr1 = *((Expression*)(exp1->handle->ptr));
Expression& cpp_expr2 = *((Expression*)(exp2->handle->ptr));
Expression* toWrap = new Expression(cpp_expr1 * cpp_expr2);
return fx_make_cptr(toWrap, expression_free, &fx_result->handle);
}

fun cpp_tree_example(): void = ccode
fun cpp_tree_example(): void = @ccode
{
Variable x("x");
Number five(5);
Expand Down
2 changes: 1 addition & 1 deletion examples/fst.fx
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ val a = [for i <- 0:n {i+1}]
for i <- 1:n {a[i] += a[i-1]}
println(f"triangular numbers: {a}")

nothrow fun is_prime(n: int)
@nothrow fun is_prime(n: int)
{
if n <= 1 {false} else if n % 2 == 0 {n == 2}
else {
Expand Down
11 changes: 4 additions & 7 deletions examples/jsonpp.fx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,10 @@ fun print_js(js: json_t, ofs: int, indent: string)
{
val W0 = 80, W1 = 100
fun all_scalars(l: json_t list) =
fold f=true for x <- l {
match x {
| JsonScalar _ => {}
| _ => break with false
}
f
}
all(for x <- l {
| JsonScalar _ => true
| _ => false
})
fun process_comments(j: json_t, indent: string) =
match j {
| JsonCommented(comm, nested_j) =>
Expand Down
4 changes: 2 additions & 2 deletions examples/mandelbrot.fx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ val N = match Sys.arguments() {
val w = N, h = N, MAX_ITER = 50
val inv = 2.0 / w

val x_ = [parallel for x <- 0:w {double(x) * inv - 1.5}]
val x_ = [@parallel for x <- 0:w {double(x) * inv - 1.5}]
val result: uint8 [,] = [
parallel
@parallel
for y <- 0:h
for x8 <- 0:(w/8)
{
Expand Down
Loading

0 comments on commit 15cccd5

Please sign in to comment.