Skip to content

Commit ddb0f81

Browse files
author
Will Bradley
committed
it is working
1 parent 2f3f1f2 commit ddb0f81

20 files changed

+143
-80
lines changed

lib/set.zion

+6-8
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,12 @@ instance HasLength (Set a) {
4444

4545
instance Iterable (Set a) a {
4646
fn iter(set Set a) fn () Maybe a {
47-
let Set(inner_map) = set
48-
return iter(
49-
map(
50-
fn (pair) {
51-
let (a, _) = pair
52-
return a
53-
},
54-
inner_map)) as fn () Maybe a
47+
let Set(inner_map) = set
48+
return iter(
49+
inner_map.map(|pair| {
50+
let (a, _) = pair
51+
return a
52+
}))
5553
}
5654
}
5755

lib/std.zion

+2-2
Original file line numberDiff line numberDiff line change
@@ -746,15 +746,15 @@ instance Iterable (Range a) a {
746746

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

749-
fn map(f fn (a) b, iterable) fn () Maybe b {
749+
fn map(iterable, f fn (a) b) fn () Maybe b {
750750
let iterator = iter(iterable)
751751
return fn () => match iterator() {
752752
Just(x) => Just(f(x))
753753
Nothing => Nothing
754754
}
755755
}
756756

757-
fn filter(f fn (a) Bool, xs_input) fn () Maybe a {
757+
fn filter(xs_input, f fn (a) Bool) fn () Maybe a {
758758
let xs = iter(xs_input)
759759
return fn() {
760760
while match xs() {

src/compiler.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "parse_state.h"
1616
#include "parser.h"
1717
#include "prefix.h"
18+
#include "tld.h"
1819
#include "utils.h"
1920
#include "zion.h"
2021

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

260+
std::set<std::string> bindings;
261+
for (auto binding: maybe_not_tld_bindings) {
262+
bindings.insert(binding);
263+
bindings.insert(tld::tld(binding));
264+
}
259265
const Module *module_rebound = prefix(bindings, module);
260266

267+
261268
/* now all locally referring vars are fully qualified */
262269
for (const Decl *decl : module_rebound->decls) {
263270
program_decls.push_back(decl);

src/main.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,7 @@ int run_job(const Job &job) {
13011301
ship_assert(!zion::tld::is_tld_type("copy"));
13021302
ship_assert(zion::tld::is_tld_type("::copy::Copy"));
13031303
ship_assert(!zion::tld::is_tld_type("::copy::copy"));
1304+
ship_assert(tld::split_fqn("::inc").size() == 1);
13041305

13051306
return EXIT_SUCCESS;
13061307
};

src/parser.cpp

+63-43
Original file line numberDiff line numberDiff line change
@@ -538,15 +538,21 @@ const Expr *parse_var_ref(ParseState &ps) {
538538
return var_ref;
539539
} else {
540540
/* we know that this was declared as a "var", so let's just automatically
541-
* load it for the user. if they want to treat is as a ref, then they need
542-
* to preface it with & */
543-
return new Application(new Var(Identifier{tld::mktld("std", "load_value"), id.location}),
544-
{var_ref});
541+
* load it for the user. */
542+
return new Application(
543+
new Var(Identifier{tld::mktld("std", "load_value"), id.location}),
544+
{var_ref});
545545
}
546546
}
547547

548548
const Expr *parse_base_expr(ParseState &ps) {
549-
if (ps.token.tk == tk_lparen) {
549+
if (ps.token.tk == tk_dot) {
550+
auto iid = gensym(ps.token.location);
551+
return new Lambda(
552+
{iid}, {type_variable(ps.token.location)},
553+
type_variable(ps.token.location),
554+
new ReturnStatement(parse_postfix_chain(ps, new Var(iid))));
555+
} else if (ps.token.tk == tk_lparen) {
550556
return parse_tuple_expr(ps);
551557
} else if (ps.token.is_ident(K(new))) {
552558
return parse_new_expr(ps);
@@ -1099,51 +1105,57 @@ const Expr *parse_literal(ParseState &ps) {
10991105
}
11001106
}
11011107

1102-
const Expr *parse_postfix_expr(ParseState &ps) {
1103-
const Expr *expr = parse_base_expr(ps);
1108+
const Expr *parse_application(ParseState &ps,
1109+
const Expr *expr,
1110+
std::vector<const Expr *> args) {
1111+
/* function call or implicit partial application (implicit lambda) */
1112+
auto location = ps.token.location;
1113+
ps.advance();
1114+
if (ps.token.tk == tk_rparen) {
1115+
ps.advance();
1116+
if (args.size() == 0) {
1117+
args.push_back(unit_expr(ps.token.location));
1118+
}
1119+
return new Application(expr, args);
1120+
} else {
1121+
while (ps.token.tk != tk_rparen) {
1122+
args.push_back(parse_expr(ps, true /*allow_for_comprehensions*/));
1123+
if (ps.token.tk == tk_comma) {
1124+
ps.advance();
1125+
} else {
1126+
expect_token(tk_rparen);
1127+
}
1128+
}
1129+
expr = new Application(expr, args);
11041130

1105-
while (!ps.line_broke() &&
1106-
(ps.token.tk == tk_lsquare || ps.token.tk == tk_lparen ||
1107-
ps.token.tk == tk_dot || ps.token.tk == tk_bang)) {
1131+
chomp_token(tk_rparen);
1132+
}
1133+
return expr;
1134+
}
1135+
1136+
const Expr *parse_postfix_chain(ParseState &ps, const Expr *expr) {
1137+
while (ps.token.tk == tk_dot ||
1138+
(!ps.line_broke() &&
1139+
(ps.token.tk == tk_lsquare || ps.token.tk == tk_lparen ||
1140+
ps.token.tk == tk_bang))) {
11081141
switch (ps.token.tk) {
11091142
case tk_bang:
11101143
expr = new As(expr, type_unit(ps.token_and_advance().location),
11111144
true /*force_cast*/);
11121145
break;
11131146
case tk_lparen: {
1114-
/* function call or implicit partial application (implicit lambda) */
1115-
auto location = ps.token.location;
1116-
ps.advance();
1117-
if (ps.token.tk == tk_rparen) {
1118-
ps.advance();
1119-
expr = new Application(expr, {unit_expr(ps.token.location)});
1120-
} else {
1121-
std::vector<const Expr *> callsite_refs;
1122-
for (int index = 0; ps.token.tk != tk_rparen; ++index) {
1123-
callsite_refs.push_back(
1124-
parse_expr(ps, true /*allow_for_comprehensions*/));
1125-
if (ps.token.tk == tk_comma) {
1126-
ps.advance();
1127-
} else {
1128-
expect_token(tk_rparen);
1129-
}
1130-
}
1131-
expr = new Application(expr, {callsite_refs});
1132-
1133-
chomp_token(tk_rparen);
1134-
}
1147+
expr = parse_application(ps, expr, {});
11351148
break;
11361149
}
11371150
case tk_dot: {
11381151
ps.advance();
11391152
expect_token(tk_identifier);
1140-
if (!islower(ps.token.text[0])) {
1141-
throw user_error(
1142-
ps.token.location,
1143-
"property accessors must start with lowercase letters");
1153+
auto iid = tld::tld(ps.identifier_and_advance());
1154+
if (!ps.line_broke() && ps.token.tk == tk_lparen) {
1155+
expr = parse_application(ps, new Var(iid), {expr});
1156+
} else {
1157+
expr = new Application(new Var(iid), {expr});
11441158
}
1145-
auto iid = ps.identifier_and_advance();
1146-
expr = new Application(new Var(iid), {expr});
11471159
break;
11481160
}
11491161
case tk_lsquare: {
@@ -1169,13 +1181,15 @@ const Expr *parse_postfix_expr(ParseState &ps) {
11691181
auto location = ps.token_and_advance().location;
11701182
auto rhs = parse_expr(ps, false /*allow_for_comprehensions*/);
11711183
expr = new Application(
1172-
new Var(Identifier{tld::mktld("std", "set_indexed_item"), location}),
1184+
new Var(
1185+
Identifier{tld::mktld("std", "set_indexed_item"), location}),
11731186
{expr, start, rhs});
11741187
} else {
11751188
expr = new Application(
1176-
new Var(Identifier{tld::mktld("std", is_slice ? "get_slice_from"
1177-
: "get_indexed_item"),
1178-
ps.token.location}),
1189+
new Var(
1190+
Identifier{tld::mktld("std", is_slice ? "get_slice_from"
1191+
: "get_indexed_item"),
1192+
ps.token.location}),
11791193
{expr, start});
11801194
}
11811195
} else {
@@ -1184,8 +1198,8 @@ const Expr *parse_postfix_expr(ParseState &ps) {
11841198

11851199
assert(is_slice);
11861200
expr = new Application(
1187-
new Var(ps.id_mapped(
1188-
Identifier{tld::mktld("std", "get_slice_from_to"), ps.token.location})),
1201+
new Var(ps.id_mapped(Identifier{
1202+
tld::mktld("std", "get_slice_from_to"), ps.token.location})),
11891203
{expr, start, stop});
11901204
}
11911205
break;
@@ -1198,6 +1212,12 @@ const Expr *parse_postfix_expr(ParseState &ps) {
11981212
return expr;
11991213
}
12001214

1215+
const Expr *parse_postfix_expr(ParseState &ps) {
1216+
const Expr *expr = parse_base_expr(ps);
1217+
1218+
return parse_postfix_chain(ps, expr);
1219+
}
1220+
12011221
const Expr *parse_cast_expr(ParseState &ps) {
12021222
const Expr *expr = parse_postfix_expr(ps);
12031223
while (!ps.line_broke() && ps.token.is_ident(K(as))) {

src/parser.h

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ const ast::Predicate *parse_predicate(ParseState &ps,
7676
bool allow_else,
7777
maybe<Identifier> name_assignment,
7878
bool allow_var_refs = true);
79+
const ast::Expr *parse_postfix_chain(ParseState &ps, const ast::Expr *expr);
7980
const ast::Predicate *unfold_application_into_predicate(
8081
const ast::Application *application);
8182
const ast::Predicate *convert_expr_to_predicate(const ast::Expr *expr);

src/prefix.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ using namespace ast;
1111
std::string prefix(const std::set<std::string> &bindings,
1212
std::string pre,
1313
std::string name) {
14-
if (tld::split_fqn(name).size() > 1) {
14+
auto names = tld::split_fqn(name);
15+
if (names.size() > 1) {
1516
return name;
1617
}
1718

src/tld.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ std::string mktld(std::string module, std::string name) {
2424
} else if (starts_with(name, PTR_TYPE_OPERATOR)) {
2525
return name;
2626
} else {
27-
return tld(module + SCOPE_SEP + name);
27+
if (starts_with(name, SCOPE_SEP)) {
28+
return tld(module + name);
29+
} else {
30+
return tld(module + SCOPE_SEP + name);
31+
}
2832
}
2933
}
3034

tests/test_bad_instance.zion

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# test: fail
2-
# expect: type error. Int != string.String
2+
# expect: type error. Int != ::string::String
33

44
class Foo a {
55
fn foo(a) Int
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# test: pass, noprelude
2+
# expect: 12
3+
4+
fn multiply(x, y) {
5+
return __builtin_multiply_int(x, y)
6+
}
7+
8+
fn main() {
9+
let multiply = 3
10+
__builtin_print_int(multiply.multiply(4))
11+
}

tests/test_chaining_multiple.zion

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# test: pass
2+
# expect: 4:5:6:7
3+
4+
fn main() {
5+
":".join([4, 5, 6, 7]).print
6+
}

tests/test_eq_ptrs.zion

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# test: fail
22
# expect: could not find a definition for
3-
# expect: std.==
3+
# expect: ::std::==
44

55
data NonComparable {
66
Monkey

tests/test_euler_02.zion

+16-16
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,25 @@ struct FibonacciIterator {
1010
}
1111

1212
fn fibonacci_sequence() {
13-
let fs = FibonacciIterator(Ref(0), Ref(1), Ref(1))
14-
return fn () {
15-
fs.index += 1
16-
if !fs.index > 2 {
17-
let next = !fs.prior + !fs.cur
18-
fs.prior = !fs.cur
19-
fs.cur = next
20-
}
21-
return Just(!fs.cur)
13+
let fs = FibonacciIterator(Ref(0), Ref(1), Ref(1))
14+
return fn () {
15+
fs.index += 1
16+
if !fs.index > 2 {
17+
let next = !fs.prior + !fs.cur
18+
fs.prior = !fs.cur
19+
fs.cur = next
2220
}
21+
return Just(!fs.cur)
22+
}
2323
}
2424

2525
fn main() {
26-
var total = 0
27-
for n in filter(even, fibonacci_sequence()) {
28-
if n > 4000000 {
29-
break
30-
}
31-
total += n
26+
var total = 0
27+
for n in fibonacci_sequence().filter(even) {
28+
if n > 4000000 {
29+
break
3230
}
33-
print(total)
31+
total += n
32+
}
33+
print(total)
3434
}

tests/test_illegal_imports.zion

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# test: fail
2-
# expect: map.needs_to_grow is not exported or does not exist
2+
# expect: ::map::needs_to_grow is not exported or does not exist
33

44
import map {needs_to_grow}
55

tests/test_import_unexported_class.zion

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# test: fail
2-
# expect: error. test_utils.UnexportedClass is not exported or does not exist
2+
# expect: error. ::test_utils::UnexportedClass is not exported or does not exist
33

44
import test_utils {UnexportedClass}
55

tests/test_iter_filter.zion

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import math {sum}
55

66
fn main() {
7-
let filtered_sum = |xs| => sum(filter(|x| => x > 2, xs))
7+
let filtered_sum = .filter(|x| => x > 2).sum
88
let a = filtered_sum([1, 2, 3, 4])
99
let b = sum(x for x in [1..4] if x > 2)
1010
assert(a == b)

tests/test_iter_map.zion

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@
44
import math {sum}
55

66
fn main() {
7-
print(sum(map(fn (x Int) Float { return from_int(x + 1) }, [1, 2, 3])))
7+
[1, 2, 3]
8+
.map(|x| Float => from_int(x + 1))
9+
.sum
10+
.print
811
}

tests/test_let_destructuring_var.zion

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# test: pass
22
# expect: 2
3-
# expect: the type is std.Ref Int
3+
# expect: the type is ::std::Ref Int
44

55
newtype N = N(var Int)
66

tests/test_ord_int_compare.zion

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# test: pass
2-
# expect: the type is std.Ordering
2+
# expect: the type is ::std::Ordering
33
# expect: PASS
44

55
fn main() {

0 commit comments

Comments
 (0)