Skip to content

Commit

Permalink
it is working
Browse files Browse the repository at this point in the history
  • Loading branch information
Will Bradley committed Jul 27, 2020
1 parent 2f3f1f2 commit ddb0f81
Show file tree
Hide file tree
Showing 20 changed files with 143 additions and 80 deletions.
14 changes: 6 additions & 8 deletions lib/set.zion
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,12 @@ instance HasLength (Set a) {

instance Iterable (Set a) a {
fn iter(set Set a) fn () Maybe a {
let Set(inner_map) = set
return iter(
map(
fn (pair) {
let (a, _) = pair
return a
},
inner_map)) as fn () Maybe a
let Set(inner_map) = set
return iter(
inner_map.map(|pair| {
let (a, _) = pair
return a
}))
}
}

Expand Down
4 changes: 2 additions & 2 deletions lib/std.zion
Original file line number Diff line number Diff line change
Expand Up @@ -746,15 +746,15 @@ instance Iterable (Range a) a {

fn compose(f, g) => fn (x) => f(g(x))

fn map(f fn (a) b, iterable) fn () Maybe b {
fn map(iterable, f fn (a) b) fn () Maybe b {
let iterator = iter(iterable)
return fn () => match iterator() {
Just(x) => Just(f(x))
Nothing => Nothing
}
}

fn filter(f fn (a) Bool, xs_input) fn () Maybe a {
fn filter(xs_input, f fn (a) Bool) fn () Maybe a {
let xs = iter(xs_input)
return fn() {
while match xs() {
Expand Down
9 changes: 8 additions & 1 deletion src/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "parse_state.h"
#include "parser.h"
#include "prefix.h"
#include "tld.h"
#include "utils.h"
#include "zion.h"

Expand Down Expand Up @@ -252,12 +253,18 @@ std::shared_ptr<Compilation> merge_compilation(
/* next, merge the entire set of modules into one program */
for (const Module *module : modules) {
/* get a list of all top-level decls */
std::set<std::string> bindings = get_top_level_decls(
std::set<std::string> maybe_not_tld_bindings = get_top_level_decls(
module->decls, module->type_decls, module->type_classes,
module->imports);

std::set<std::string> bindings;
for (auto binding: maybe_not_tld_bindings) {
bindings.insert(binding);
bindings.insert(tld::tld(binding));
}
const Module *module_rebound = prefix(bindings, module);


/* now all locally referring vars are fully qualified */
for (const Decl *decl : module_rebound->decls) {
program_decls.push_back(decl);
Expand Down
1 change: 1 addition & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,7 @@ int run_job(const Job &job) {
ship_assert(!zion::tld::is_tld_type("copy"));
ship_assert(zion::tld::is_tld_type("::copy::Copy"));
ship_assert(!zion::tld::is_tld_type("::copy::copy"));
ship_assert(tld::split_fqn("::inc").size() == 1);

return EXIT_SUCCESS;
};
Expand Down
106 changes: 63 additions & 43 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,15 +538,21 @@ const Expr *parse_var_ref(ParseState &ps) {
return var_ref;
} else {
/* we know that this was declared as a "var", so let's just automatically
* load it for the user. if they want to treat is as a ref, then they need
* to preface it with & */
return new Application(new Var(Identifier{tld::mktld("std", "load_value"), id.location}),
{var_ref});
* load it for the user. */
return new Application(
new Var(Identifier{tld::mktld("std", "load_value"), id.location}),
{var_ref});
}
}

const Expr *parse_base_expr(ParseState &ps) {
if (ps.token.tk == tk_lparen) {
if (ps.token.tk == tk_dot) {
auto iid = gensym(ps.token.location);
return new Lambda(
{iid}, {type_variable(ps.token.location)},
type_variable(ps.token.location),
new ReturnStatement(parse_postfix_chain(ps, new Var(iid))));
} else if (ps.token.tk == tk_lparen) {
return parse_tuple_expr(ps);
} else if (ps.token.is_ident(K(new))) {
return parse_new_expr(ps);
Expand Down Expand Up @@ -1099,51 +1105,57 @@ const Expr *parse_literal(ParseState &ps) {
}
}

const Expr *parse_postfix_expr(ParseState &ps) {
const Expr *expr = parse_base_expr(ps);
const Expr *parse_application(ParseState &ps,
const Expr *expr,
std::vector<const Expr *> args) {
/* function call or implicit partial application (implicit lambda) */
auto location = ps.token.location;
ps.advance();
if (ps.token.tk == tk_rparen) {
ps.advance();
if (args.size() == 0) {
args.push_back(unit_expr(ps.token.location));
}
return new Application(expr, args);
} else {
while (ps.token.tk != tk_rparen) {
args.push_back(parse_expr(ps, true /*allow_for_comprehensions*/));
if (ps.token.tk == tk_comma) {
ps.advance();
} else {
expect_token(tk_rparen);
}
}
expr = new Application(expr, args);

while (!ps.line_broke() &&
(ps.token.tk == tk_lsquare || ps.token.tk == tk_lparen ||
ps.token.tk == tk_dot || ps.token.tk == tk_bang)) {
chomp_token(tk_rparen);
}
return expr;
}

const Expr *parse_postfix_chain(ParseState &ps, const Expr *expr) {
while (ps.token.tk == tk_dot ||
(!ps.line_broke() &&
(ps.token.tk == tk_lsquare || ps.token.tk == tk_lparen ||
ps.token.tk == tk_bang))) {
switch (ps.token.tk) {
case tk_bang:
expr = new As(expr, type_unit(ps.token_and_advance().location),
true /*force_cast*/);
break;
case tk_lparen: {
/* function call or implicit partial application (implicit lambda) */
auto location = ps.token.location;
ps.advance();
if (ps.token.tk == tk_rparen) {
ps.advance();
expr = new Application(expr, {unit_expr(ps.token.location)});
} else {
std::vector<const Expr *> callsite_refs;
for (int index = 0; ps.token.tk != tk_rparen; ++index) {
callsite_refs.push_back(
parse_expr(ps, true /*allow_for_comprehensions*/));
if (ps.token.tk == tk_comma) {
ps.advance();
} else {
expect_token(tk_rparen);
}
}
expr = new Application(expr, {callsite_refs});

chomp_token(tk_rparen);
}
expr = parse_application(ps, expr, {});
break;
}
case tk_dot: {
ps.advance();
expect_token(tk_identifier);
if (!islower(ps.token.text[0])) {
throw user_error(
ps.token.location,
"property accessors must start with lowercase letters");
auto iid = tld::tld(ps.identifier_and_advance());
if (!ps.line_broke() && ps.token.tk == tk_lparen) {
expr = parse_application(ps, new Var(iid), {expr});
} else {
expr = new Application(new Var(iid), {expr});
}
auto iid = ps.identifier_and_advance();
expr = new Application(new Var(iid), {expr});
break;
}
case tk_lsquare: {
Expand All @@ -1169,13 +1181,15 @@ const Expr *parse_postfix_expr(ParseState &ps) {
auto location = ps.token_and_advance().location;
auto rhs = parse_expr(ps, false /*allow_for_comprehensions*/);
expr = new Application(
new Var(Identifier{tld::mktld("std", "set_indexed_item"), location}),
new Var(
Identifier{tld::mktld("std", "set_indexed_item"), location}),
{expr, start, rhs});
} else {
expr = new Application(
new Var(Identifier{tld::mktld("std", is_slice ? "get_slice_from"
: "get_indexed_item"),
ps.token.location}),
new Var(
Identifier{tld::mktld("std", is_slice ? "get_slice_from"
: "get_indexed_item"),
ps.token.location}),
{expr, start});
}
} else {
Expand All @@ -1184,8 +1198,8 @@ const Expr *parse_postfix_expr(ParseState &ps) {

assert(is_slice);
expr = new Application(
new Var(ps.id_mapped(
Identifier{tld::mktld("std", "get_slice_from_to"), ps.token.location})),
new Var(ps.id_mapped(Identifier{
tld::mktld("std", "get_slice_from_to"), ps.token.location})),
{expr, start, stop});
}
break;
Expand All @@ -1198,6 +1212,12 @@ const Expr *parse_postfix_expr(ParseState &ps) {
return expr;
}

const Expr *parse_postfix_expr(ParseState &ps) {
const Expr *expr = parse_base_expr(ps);

return parse_postfix_chain(ps, expr);
}

const Expr *parse_cast_expr(ParseState &ps) {
const Expr *expr = parse_postfix_expr(ps);
while (!ps.line_broke() && ps.token.is_ident(K(as))) {
Expand Down
1 change: 1 addition & 0 deletions src/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const ast::Predicate *parse_predicate(ParseState &ps,
bool allow_else,
maybe<Identifier> name_assignment,
bool allow_var_refs = true);
const ast::Expr *parse_postfix_chain(ParseState &ps, const ast::Expr *expr);
const ast::Predicate *unfold_application_into_predicate(
const ast::Application *application);
const ast::Predicate *convert_expr_to_predicate(const ast::Expr *expr);
Expand Down
3 changes: 2 additions & 1 deletion src/prefix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ using namespace ast;
std::string prefix(const std::set<std::string> &bindings,
std::string pre,
std::string name) {
if (tld::split_fqn(name).size() > 1) {
auto names = tld::split_fqn(name);
if (names.size() > 1) {
return name;
}

Expand Down
6 changes: 5 additions & 1 deletion src/tld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ std::string mktld(std::string module, std::string name) {
} else if (starts_with(name, PTR_TYPE_OPERATOR)) {
return name;
} else {
return tld(module + SCOPE_SEP + name);
if (starts_with(name, SCOPE_SEP)) {
return tld(module + name);
} else {
return tld(module + SCOPE_SEP + name);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/test_bad_instance.zion
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test: fail
# expect: type error. Int != string.String
# expect: type error. Int != ::string::String

class Foo a {
fn foo(a) Int
Expand Down
11 changes: 11 additions & 0 deletions tests/test_chaining_function_calls.zion
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# test: pass, noprelude
# expect: 12

fn multiply(x, y) {
return __builtin_multiply_int(x, y)
}

fn main() {
let multiply = 3
__builtin_print_int(multiply.multiply(4))
}
6 changes: 6 additions & 0 deletions tests/test_chaining_multiple.zion
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# test: pass
# expect: 4:5:6:7

fn main() {
":".join([4, 5, 6, 7]).print
}
2 changes: 1 addition & 1 deletion tests/test_eq_ptrs.zion
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# test: fail
# expect: could not find a definition for
# expect: std.==
# expect: ::std::==

data NonComparable {
Monkey
Expand Down
32 changes: 16 additions & 16 deletions tests/test_euler_02.zion
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,25 @@ struct FibonacciIterator {
}

fn fibonacci_sequence() {
let fs = FibonacciIterator(Ref(0), Ref(1), Ref(1))
return fn () {
fs.index += 1
if !fs.index > 2 {
let next = !fs.prior + !fs.cur
fs.prior = !fs.cur
fs.cur = next
}
return Just(!fs.cur)
let fs = FibonacciIterator(Ref(0), Ref(1), Ref(1))
return fn () {
fs.index += 1
if !fs.index > 2 {
let next = !fs.prior + !fs.cur
fs.prior = !fs.cur
fs.cur = next
}
return Just(!fs.cur)
}
}

fn main() {
var total = 0
for n in filter(even, fibonacci_sequence()) {
if n > 4000000 {
break
}
total += n
var total = 0
for n in fibonacci_sequence().filter(even) {
if n > 4000000 {
break
}
print(total)
total += n
}
print(total)
}
2 changes: 1 addition & 1 deletion tests/test_illegal_imports.zion
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test: fail
# expect: map.needs_to_grow is not exported or does not exist
# expect: ::map::needs_to_grow is not exported or does not exist

import map {needs_to_grow}

Expand Down
2 changes: 1 addition & 1 deletion tests/test_import_unexported_class.zion
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test: fail
# expect: error. test_utils.UnexportedClass is not exported or does not exist
# expect: error. ::test_utils::UnexportedClass is not exported or does not exist

import test_utils {UnexportedClass}

Expand Down
2 changes: 1 addition & 1 deletion tests/test_iter_filter.zion
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import math {sum}

fn main() {
let filtered_sum = |xs| => sum(filter(|x| => x > 2, xs))
let filtered_sum = .filter(|x| => x > 2).sum
let a = filtered_sum([1, 2, 3, 4])
let b = sum(x for x in [1..4] if x > 2)
assert(a == b)
Expand Down
5 changes: 4 additions & 1 deletion tests/test_iter_map.zion
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
import math {sum}

fn main() {
print(sum(map(fn (x Int) Float { return from_int(x + 1) }, [1, 2, 3])))
[1, 2, 3]
.map(|x| Float => from_int(x + 1))
.sum
.print
}
2 changes: 1 addition & 1 deletion tests/test_let_destructuring_var.zion
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# test: pass
# expect: 2
# expect: the type is std.Ref Int
# expect: the type is ::std::Ref Int

newtype N = N(var Int)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_ord_int_compare.zion
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test: pass
# expect: the type is std.Ordering
# expect: the type is ::std::Ordering
# expect: PASS

fn main() {
Expand Down
Loading

0 comments on commit ddb0f81

Please sign in to comment.