Skip to content

Commit 9b22416

Browse files
committed
Some fixes from stdlib testing
1 parent 5dcd903 commit 9b22416

File tree

3 files changed

+52
-22
lines changed

3 files changed

+52
-22
lines changed

src/validation.jl

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ vst1_value(vcx::Validation1Context, st::SyntaxTree; need_value=true) = @stm st b
131131
[K".=" l r] -> vst1_dotassign_lhs(vcx, l) & vst1_value(vcx, r)
132132
[K".op=" l op r] -> vst1_dotassign_lhs(vcx, l) & vst1_ident(vcx, op) & vst1_value(vcx, r)
133133

134-
[K"function" _...] -> !vcx.inner_cond || vcx.toplevel ? vst1_function(vcx, st) :
134+
[K"function" _...] -> !vcx.inner_cond ? vst1_function(vcx, st) :
135135
fail(vcx, st, "conditional inner method definitions are not supported; use `()->()` syntax instead")
136136
[K"call" _...] -> vst1_call(vcx, st)
137137
[K"dotcall" _...] -> vst1_dotcall(vcx, st)
@@ -155,12 +155,10 @@ vst1_value(vcx::Validation1Context, st::SyntaxTree; need_value=true) = @stm st b
155155
[K"quote" x] -> vcx.unexpanded ? vst0_quoted(with(vcx, :quote_level=>1), x) :
156156
fail(vcx, st, "interpolating quote not valid in AST after macro expansion")
157157
[K"$" x] -> fail(vcx, st, raw"`$` expression outside string or quote")
158-
[K"tuple" xs... [K"parameters" kws...]] ->
159-
allv(vst1_splat_or_val, vcx, xs) & allv(vst1_call_arg, vcx, kws)
160-
[K"tuple" xs...] -> allv(vst1_splat_or_val, vcx, xs)
158+
[K"tuple" _...] -> vst1_value_tuple(vcx, st)
161159
[K"." x y] -> vst1_value(vcx, x) & vst1_dot_rhs(vcx, y)
162160
[K"." x] -> vst1_value(vcx, x)
163-
[K":"] -> true # ast TODO: this doesn't need to be a kind. note a:b is a call, this is a[:] or just :
161+
[K":"] -> true # ast TODO: `a:b` is identifier, lone `:` should be identifier, `a[:]` should be this kind
164162
[K"curly" t xs...] -> vst1_value(vcx, t) & allv(vst1_value_curly_typevar, vcx, xs)
165163
[K"where" lhs rhs] -> vst1_value(vcx, lhs) & vst1_where_rhs(vcx, rhs)
166164
[K"string" xs...] -> allv(vst1_value, vcx, xs)
@@ -216,15 +214,18 @@ vst1_value(vcx::Validation1Context, st::SyntaxTree; need_value=true) = @stm st b
216214
allv(vst1_ident, vcx, b1) &
217215
allv(vst1_ident, vcx, b2) &
218216
vst1_lam(vcx, st[3])
217+
[K"scope_block" x] -> vst1_value(vcx, x; need_value)
219218
[K"generated"] -> true
220-
([K"foreigncall" f [K"static_eval" rt] [K"static_eval" argt_svec] args...],
221-
when=kind(f) in (K"Symbol", K"Identifier")) ->
222-
vst1_value(vcx, rt) & vst1_value(vcx, argt_svec) & allv(vst1_value, vcx, args)
219+
# TODO: could probably be validated more
220+
[K"foreigncall" f [K"static_eval" rt] [K"static_eval" argt_svec] args...] ->
221+
vst1_foreigncall_fname(vcx, f) & vst1_value(vcx, rt) &
222+
vst1_value(vcx, argt_svec) & allv(vst1_value, vcx, args)
223223
[K"cfunction" t [K"static_eval" fptr] [K"static_eval" rt] [K"static_eval" argt_svec] [K"Symbol"]] ->
224-
vst1_value(vcx, t) & vst1_value(vcx, fptr) & vst1_value(vcx, rt) & vst1_value(vcx, argt_svec)
224+
vst1_value(vcx, t) & vst1_value(vcx, fptr) &
225+
vst1_value(vcx, rt) & vst1_value(vcx, argt_svec)
225226
[K"cfunction" t fptr [K"static_eval" rt] [K"static_eval" argt_svec] [K"Symbol"]] ->
226-
vst1_value(vcx, t) & vst1_value(vcx, fptr) & vst1_value(vcx, rt) & vst1_value(vcx, argt_svec)
227-
[K"scope_block" x] -> vst1_value(vcx, x; need_value)
227+
vst1_value(vcx, t) & vst1_value(vcx, fptr) &
228+
vst1_value(vcx, rt) & vst1_value(vcx, argt_svec)
228229

229230
# Only from macro expansions producing Expr(:toplevel, ...). We don't want
230231
# to recurse on the contained expression since `K"escape"` can wrap nearly
@@ -283,6 +284,7 @@ vst1_stmt(vcx::Validation1Context, st::SyntaxTree) = @stm st begin
283284
([K"global" xs...], when=!vcx.toplevel) -> allv(vst1_inner_global_decl, vcx, xs)
284285
[K"symbolic_label"] -> true
285286
[K"symbolic_goto"] -> true
287+
[K"latestworld_if_toplevel"] -> true
286288

287289
(_, run=pass_or_err(vst1_toplevel_only_stmt, vcx, st), when=run.known) ->
288290
run.pass && (vcx.toplevel || fail(vcx, st, "this syntax is only allowed in top level code"))
@@ -312,7 +314,6 @@ vst1_toplevel_only_stmt(vcx::Validation1Context, st::SyntaxTree) = @stm st begin
312314
[K"public" xs...] -> allv(vst1_ident, vcx, xs)
313315
[K"export" xs...] -> allv(vst1_ident, vcx, xs)
314316
[K"latestworld"] -> true
315-
[K"latestworld_if_toplevel"] -> true
316317
_ -> false
317318
end
318319

@@ -347,21 +348,33 @@ function vst1_importpath(vcx, st; dots_ok)
347348
return ok && seen_first
348349
end
349350

351+
vst1_value_tuple(vcx, st) = @stm st begin
352+
[K"tuple" [K"parameters" kws...]] -> allv(vst1_call_arg, vcx, kws)
353+
[K"tuple" _ _... [K"parameters" _ _...]] ->
354+
fail(vcx, st[end], "cannot mix tuple `(a,b,c)` and named tuple `(;a,b,c)` syntax")
355+
[K"tuple" xs...] -> allv(vst1_splat_or_val, vcx, xs)
356+
_ -> fail(vcx, st, "malformed tuple")
357+
end
358+
350359
vst1_block(vcx, st; need_value=true) = @stm st begin
351360
[K"block"] -> true
352361
([K"block" xs...], when=!need_value) -> allv(vst1_stmt, vcx, xs)
353362
[K"block" xs... val] -> allv(vst1_stmt, vcx, xs) & vst1_value(vcx, val)
354363
_ -> fail(vcx, st, "expected `block`")
355364
end
356365

366+
# Usually block-wrapped, but not always.
357367
vst1_else(vcx, st; need_value) = @stm st begin
358-
[K"block" _...] -> vst1_block(vcx, st; need_value)
359-
[K"elseif" cond t f] ->
360-
vst1_value(vcx, cond) & vst1_block(vcx, t; need_value) & vst1_else(vcx, f; need_value)
368+
[K"elseif" cond t] -> vst1_value(vcx, cond) & vst1_value(vcx, t; need_value)
369+
[K"elseif" cond t f] -> vst1_value(vcx, cond) &
370+
vst1_value(vcx, t; need_value) & vst1_else(vcx, f; need_value)
361371
_ -> vst1_value(vcx, st; need_value)
362372
end
363373

364374
# TODO: catch and else are in value position
375+
# ast TODO: While the AST is more readable than Expr's try-catch, it's difficult
376+
# enough to unpack that we should consider changing it, especially if we intend
377+
# to support multiple catch-blocks at some point
365378
vst1_try(vcx, st) = @stm st begin
366379
[K"try" _] -> fail(vcx, st, "try without catch or finally")
367380
[K"try" b1 [K"catch" err body2...]] ->
@@ -517,8 +530,7 @@ end
517530
# assignments (interpreted as kwargs) must have a simple LHS, and splat is OK.
518531
vst1_call_arg(vcx, st) = @stm st begin
519532
[K"=" id val] -> vst1_ident(vcx, id) & vst1_value(vcx, val)
520-
[K"..." x] -> vst1_value(vcx, x) # complex assignment in here is OK
521-
_ -> vst1_value(vcx, st)
533+
_ -> vst1_splat_or_val(vcx, st) # complex assignment in `...` is OK
522534
end
523535

524536
# Arg to `parameters` (post-semicolon) in a call (not function decl) can be:
@@ -673,6 +685,7 @@ vst1_param_req_or_tuple(vcx, st) = @stm st begin
673685
end
674686

675687
vst1_simple_tuple_lhs(vcx, st) = @stm st begin
688+
[K"tuple" [K"parameters" kws...]] -> allv(vst1_ident_lhs, vcx, kws)
676689
[K"tuple" xs...] -> allv(vst1_simple_tuple_lhs, vcx, xs)
677690
_ -> vst1_ident_lhs(vcx, st)
678691
end
@@ -748,6 +761,16 @@ vst1_struct_field(vcx, st) = @stm st begin
748761
_ -> vst1_stmt(vcx, st)
749762
end
750763

764+
# TODO count(kind(x)===k for x in xs)
765+
# working around a revise bug that fails with anonymous functions
766+
function _num_of_kind(xs, k)
767+
n = 0
768+
for x in xs
769+
kind(x) === k && (n += 1)
770+
end
771+
return n
772+
end
773+
751774
# syntax TODO: (local/global (= lhs rhs)) forms should probably reject the same lhss as const (ref and .)
752775
# TODO: We can do some destructuring checks here (e.g. fail `(a,b,c) = (1,2)`)
753776
# compat:
@@ -758,7 +781,7 @@ vst1_assign_lhs(vcx, st; in_const=false, in_tuple=false, disallow_type=false) =
758781
[K"tuple" [K"parameters" xs...]] -> allv(vst1_symdecl, vcx, xs)
759782
[K"tuple" xs...] ->
760783
allv(vst1_assign_lhs, vcx, xs; in_const, in_tuple=true) &
761-
(count(kind(x)===K"..." for x in xs) <= 1 ||
784+
(_num_of_kind(xs, K"...") <= 1 ||
762785
fail(vcx, st, "multiple `...` in destructuring assignment are ambiguous"))
763786
# Parser produces this in too many places
764787
# [K"call" _...] ->
@@ -815,9 +838,8 @@ vst1_arraylike(vcx, st) = @stm st begin
815838
_ -> false
816839
end
817840

818-
# TODO: Are there things we can rule out from appearing in `...`?
819841
vst1_splat_or_val(vcx, st) = @stm st begin
820-
[K"..." x] -> vst1_value(vcx, x)
842+
[K"..." x] -> vst1_splat_or_val(vcx, x)
821843
[K"..." _...] -> fail("expected one argument to `...`")
822844
_ -> vst1_value(vcx, st)
823845
end
@@ -853,6 +875,14 @@ vst1_documented(vcx, st) = @stm st begin
853875
_ -> fail(vcx, st, "`$(kind(st))` cannot be annotated with a docstring")
854876
end
855877

878+
vst1_foreigncall_fname(vcx, st) = @stm st begin
879+
[K"Symbol"] -> true
880+
[K"Identifier"] -> true
881+
[K"static_eval" x] -> vst1_foreigncall_fname(vcx, x)
882+
[K"tuple" xs...] -> allv(vst1_value, vcx, xs) # TODO
883+
_ -> fail(vcx, st, "invalid foreigncall function name")
884+
end
885+
856886
"""
857887
For convenience, much of the validation code for st0 (non-macro-expanded trees) is
858888
shared with that for st1 (macro-expanded trees). The main differences:

test/function_calls_ir.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,4 +650,4 @@ tuple(((xs...)...)...)
650650
#---------------------
651651
LoweringError:
652652
(xs...)
653-
#└───┘ ── `...` expression outside call
653+
#└───┘ ── unexpected splat not in `call`, `tuple`, `curly`, or array expression

test/misc_ir.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ LoweringError:
148148
#---------------------
149149
LoweringError:
150150
(a=1; b=2, c=3)
151-
# └────────┘ ── unexpected semicolon in tuple - use `,` to separate tuple elements
151+
# └────────┘ ── cannot mix tuple `(a,b,c)` and named tuple `(;a,b,c)` syntax
152152

153153
########################################
154154
# Error: Named tuple field dots in rhs

0 commit comments

Comments
 (0)