Skip to content

Commit 8fee17d

Browse files
committed
jl_value_t as parser options for improved flexibility
1 parent aea71b2 commit 8fee17d

File tree

5 files changed

+38
-44
lines changed

5 files changed

+38
-44
lines changed

base/meta.jl

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -150,19 +150,24 @@ struct ParseError <: Exception
150150
end
151151

152152
function _jl_parse(text::AbstractString, filename::AbstractString,
153-
pos::Integer, rule::Integer)
153+
pos::Integer; options...)
154154
if pos < 1 || pos > ncodeunits(text) + 1
155155
throw(BoundsError(text, pos))
156156
end
157-
# Technically only need pointers to UTF-8 buffers here. For now converting
158-
# to a plain String is the easy way to ensure that.
157+
# Technically only need pointers to UTF-8 buffers here. Converting to a
158+
# plain String is the easy way to ensure that.
159159
filename = String(filename)
160160
text = String(text)
161+
options = values(options)
162+
if length(options) == 1 && haskey(options, :rule)
163+
# Hack: Pass rule as a symbol for benefit of jl_fl_parse
164+
options = options.rule
165+
end
161166
# Call into the parser which can be replaced globally during bootstrap with
162167
# jl_set_parser
163168
ex,pos = ccall(:jl_parse, Any,
164-
(Ptr{UInt8}, Csize_t, Ptr{UInt8}, Csize_t, Csize_t, Cint),
165-
text, sizeof(text), filename, sizeof(filename), pos-1, rule)
169+
(Ptr{UInt8}, Csize_t, Ptr{UInt8}, Csize_t, Csize_t, Any),
170+
text, sizeof(text), filename, sizeof(filename), pos-1, options)
166171
# internally, pos is a zero-based byte offset - convert back.
167172
ex, pos+1
168173
end
@@ -190,12 +195,7 @@ julia> Meta.parse("x = 3, y = 5", 5)
190195
function parse(str::AbstractString, pos::Integer; greedy::Bool=true, raise::Bool=true,
191196
depwarn::Bool=true)
192197
filename = "none"
193-
JL_PARSE_ATOM = 1
194-
JL_PARSE_STATEMENT = 2
195-
rule = greedy ? JL_PARSE_STATEMENT : JL_PARSE_ATOM
196-
# For now, assume all parser warnings are depwarns
197-
# TODO: remove parser-depwarn; parser no longer emits warnings.
198-
ex, pos = _jl_parse(str, "none", pos, rule)
198+
ex, pos = _jl_parse(str, "none", pos; rule=greedy ? :statement : :atom)
199199
if raise && isa(ex,Expr) && ex.head === :error
200200
throw(ParseError(ex.args[1]))
201201
end
@@ -240,13 +240,11 @@ function parse(str::AbstractString; raise::Bool=true, depwarn::Bool=true)
240240
end
241241

242242
function parseatom(text::AbstractString, pos::Integer; filename="none")
243-
JL_PARSE_ATOM = 1
244-
return _jl_parse(text, filename, pos, JL_PARSE_ATOM)
243+
return _jl_parse(text, filename, pos; rule=:atom)
245244
end
246245

247246
function parseall(text::AbstractString; filename="none")
248-
JL_PARSE_ALL = 3
249-
ex,_ = _jl_parse(text, filename, 1, JL_PARSE_ALL)
247+
ex,_ = _jl_parse(text, filename, 1; rule=:all)
250248
return ex
251249
end
252250

src/ast.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ jl_sym_t *gc_preserve_begin_sym; jl_sym_t *gc_preserve_end_sym;
6767
jl_sym_t *coverageeffect_sym; jl_sym_t *escape_sym;
6868
jl_sym_t *aliasscope_sym; jl_sym_t *popaliasscope_sym;
6969
jl_sym_t *optlevel_sym;
70+
jl_sym_t *atom_sym; jl_sym_t *statement_sym; jl_sym_t *all_sym;
7071

7172
static uint8_t flisp_system_image[] = {
7273
#include <julia_flisp.boot.inc>
@@ -402,6 +403,9 @@ void jl_init_common_symbols(void)
402403
coverageeffect_sym = jl_symbol("code_coverage_effect");
403404
aliasscope_sym = jl_symbol("aliasscope");
404405
popaliasscope_sym = jl_symbol("popaliasscope");
406+
atom_sym = jl_symbol("atom");
407+
statement_sym = jl_symbol("statement");
408+
all_sym = jl_symbol("all");
405409
}
406410

407411
JL_DLLEXPORT void jl_lisp_prompt(void)
@@ -785,16 +789,20 @@ static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v)
785789
// content to `filename`. Return an svec of (parse_result, final_pos)
786790
JL_DLLEXPORT jl_value_t *jl_fl_parse(const char* text, size_t text_len,
787791
const char* filename, size_t filename_len,
788-
size_t offset, int rule)
792+
size_t offset, jl_value_t *options)
789793
{
790794
JL_TIMING(PARSING);
791795
if (offset > text_len) {
792796
jl_value_t *textstr = jl_pchar_to_string(text, text_len);
793797
JL_GC_PUSH1(&textstr);
794798
jl_bounds_error(textstr, jl_box_long(offset));
795799
}
796-
else if (offset != 0 && rule == JL_PARSE_ALL) {
797-
jl_error("Partial parsing not support by top level grammar rule");
800+
jl_sym_t *rule = (jl_sym_t*)options;
801+
if (rule != atom_sym && rule != statement_sym && rule != all_sym) {
802+
jl_error("jl_fl_parse: unrecognized parse options");
803+
}
804+
if (offset != 0 && rule == all_sym) {
805+
jl_error("Parse `all`: offset not supported");
798806
}
799807

800808
jl_ast_context_t *ctx = jl_ast_ctx_enter();
@@ -803,23 +811,19 @@ JL_DLLEXPORT jl_value_t *jl_fl_parse(const char* text, size_t text_len,
803811
value_t fl_filename = cvalue_static_cstrn(fl_ctx, filename, filename_len);
804812
value_t fl_expr;
805813
size_t pos1 = 0;
806-
if (rule == JL_PARSE_ALL) {
814+
if (rule == all_sym) {
807815
value_t e = fl_applyn(fl_ctx, 2, symbol_value(symbol(fl_ctx, "jl-parse-all")),
808816
fl_text, fl_filename);
809817
fl_expr = e;
810818
pos1 = e == fl_ctx->FL_EOF ? text_len : 0;
811819
}
812-
else if (rule == JL_PARSE_STATEMENT || rule == JL_PARSE_ATOM) {
813-
value_t greedy = rule == JL_PARSE_STATEMENT ? fl_ctx->T : fl_ctx->F;
820+
else {
821+
value_t greedy = rule == statement_sym ? fl_ctx->T : fl_ctx->F;
814822
value_t p = fl_applyn(fl_ctx, 4, symbol_value(symbol(fl_ctx, "jl-parse-one")),
815823
fl_text, fl_filename, fixnum(offset), greedy);
816824
fl_expr = car_(p);
817825
pos1 = tosize(fl_ctx, cdr_(p), "parse");
818826
}
819-
else {
820-
jl_ast_ctx_leave(ctx);
821-
jl_errorf("Unknown parse rule %d", (int)rule);
822-
}
823827

824828
// Convert to julia values
825829
jl_value_t *expr=NULL, *end_offset=NULL;

src/frontend.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ JL_DLLEXPORT void jl_set_parser(jl_parse_func_t parser)
2020

2121
JL_DLLEXPORT jl_value_t *jl_parse(const char* text, size_t text_len,
2222
const char* filename, size_t filename_len,
23-
size_t offset, int rule)
23+
size_t offset, jl_value_t* options)
2424
{
25-
return (*jl_current_parser)(text, text_len, filename, filename_len, offset, rule);
25+
return (*jl_current_parser)(text, text_len, filename, filename_len, offset, options);
2626
}
2727

2828
// C API
@@ -31,18 +31,17 @@ JL_DLLEXPORT jl_value_t *jl_parse_all(const char *text, size_t text_len,
3131
const char *filename, size_t filename_len)
3232
{
3333
jl_value_t *p = jl_parse(text, text_len, filename, filename_len,
34-
0, JL_PARSE_ALL);
34+
0, (jl_value_t*)all_sym);
3535
return jl_svecref(p, 0);
3636
}
3737

3838
// this is for parsing one expression out of a string, keeping track of
3939
// the current position.
40-
// FIXME: Add filename?
4140
JL_DLLEXPORT jl_value_t *jl_parse_string(const char *text, size_t text_len,
4241
int pos0, int greedy)
4342
{
4443
return jl_parse(text, text_len, "none", 4,
45-
pos0, greedy ? JL_PARSE_STATEMENT : JL_PARSE_ATOM);
44+
pos0, greedy ? (jl_value_t*)statement_sym : (jl_value_t*)atom_sym);
4645
}
4746

4847
// deprecated

src/julia.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,18 +1600,7 @@ JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist);
16001600
JL_DLLEXPORT jl_value_t *jl_restore_incremental(const char *fname, jl_array_t *depmods);
16011601
JL_DLLEXPORT jl_value_t *jl_restore_incremental_from_buf(const char *buf, size_t sz, jl_array_t *depmods);
16021602

1603-
// front end interface
1604-
typedef enum {
1605-
JL_PARSE_ATOM = 1,
1606-
JL_PARSE_STATEMENT = 2,
1607-
JL_PARSE_ALL = 3,
1608-
} jl_parse_rule_t;
1609-
16101603
// parsing
1611-
JL_DLLEXPORT jl_value_t *jl_parse(const char* text, size_t text_len,
1612-
const char* filename, size_t filename_len,
1613-
size_t offset, int rule);
1614-
// Convenince functions
16151604
JL_DLLEXPORT jl_value_t *jl_parse_all(const char *str, size_t len,
16161605
const char *filename, size_t filename_len);
16171606
JL_DLLEXPORT jl_value_t *jl_parse_string(const char *str, size_t len,

src/julia_internal.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -638,13 +638,16 @@ jl_tupletype_t *arg_type_tuple(jl_value_t *arg1, jl_value_t **args, size_t nargs
638638

639639
int jl_has_meta(jl_array_t *body, jl_sym_t *sym);
640640

641-
// Parser replacement
642-
typedef jl_value_t* (*jl_parse_func_t)(const char*, size_t, const char*, size_t, size_t, int);
641+
// Experimental parser replacement API
642+
JL_DLLEXPORT jl_value_t *jl_parse(const char* text, size_t text_len,
643+
const char* filename, size_t filename_len,
644+
size_t offset, jl_value_t *options);
645+
typedef jl_value_t* (*jl_parse_func_t)(const char*, size_t, const char*, size_t, size_t, jl_value_t*);
643646
JL_DLLEXPORT void jl_set_parser(jl_parse_func_t parser);
644647
// Builtin flisp parser
645648
JL_DLLEXPORT jl_value_t *jl_fl_parse(const char* text, size_t text_len,
646649
const char* filename, size_t filename_len,
647-
size_t offset, int rule);
650+
size_t offset, jl_value_t *options);
648651

649652
//--------------------------------------------------
650653
// Backtraces
@@ -1174,6 +1177,7 @@ extern jl_sym_t *gc_preserve_begin_sym; extern jl_sym_t *gc_preserve_end_sym;
11741177
extern jl_sym_t *failed_sym; extern jl_sym_t *done_sym; extern jl_sym_t *runnable_sym;
11751178
extern jl_sym_t *coverageeffect_sym; extern jl_sym_t *escape_sym;
11761179
extern jl_sym_t *optlevel_sym;
1180+
extern jl_sym_t *atom_sym; extern jl_sym_t *statement_sym; extern jl_sym_t *all_sym;
11771181

11781182
struct _jl_sysimg_fptrs_t;
11791183

0 commit comments

Comments
 (0)