Skip to content

Commit

Permalink
Add labels and gotos. (Fixes JuliaLang#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
dcjones committed Feb 6, 2014
1 parent d2d9bd9 commit 6e5ce3c
Show file tree
Hide file tree
Showing 14 changed files with 94 additions and 19 deletions.
8 changes: 8 additions & 0 deletions base/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,14 @@ macro inbounds(blk)
:(@boundscheck false $(esc(blk)))
end

macro label(name::Symbol)
SymbolicLabelNode(name)
end

macro goto(name::Symbol)
SymbolicGotoNode(name)
end

# NOTE: Base shares Array with Core so we can add definitions to it

Array{T,N}(::Type{T}, d::NTuple{N,Int}) =
Expand Down
12 changes: 10 additions & 2 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@
# label::Int
#end

#immutable SymbolicLabelNode
# label::Symbol
#end

#immutable SymbolicGotoNode
# label::Symbol
#end

#immutable QuoteNode
# value
#end
Expand Down Expand Up @@ -133,8 +141,8 @@ export
InexactError, InterruptException, MemoryError, OverflowError,
StackOverflowError, UndefRefError,
# AST representation
Expr, GotoNode, LabelNode, LineNumberNode, QuoteNode, SymbolNode, TopNode,
GetfieldNode,
Expr, GotoNode, LabelNode, SymbolicLabelNode, SymbolicGotoNode,
LineNumberNode, QuoteNode, SymbolNode, TopNode, GetfieldNode,
# object model functions
apply, arraylen, arrayref, arrayset, arraysize, fieldtype, getfield,
setfield, yieldto, throw, tuple, tuplelen, tupleref, is, ===, isdefined,
Expand Down
4 changes: 3 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1298,4 +1298,6 @@ export
@sprintf,
@deprecate,
@boundscheck,
@inbounds
@inbounds,
@label,
@goto
4 changes: 2 additions & 2 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1081,7 +1081,7 @@ end
function findlabel(body, l)
for i=1:length(body)
b = body[i]
if isa(b,LabelNode) && b.label==l
if (isa(b,LabelNode) || isa(b,SymbolicLabelNode)) && b.label==l
return i
end
end
Expand Down Expand Up @@ -1305,7 +1305,7 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
end
end
pc´ = pc+1
if isa(stmt,GotoNode)
if isa(stmt,GotoNode) || isa(stmt,SymbolicGotoNode)
pc´ = findlabel(body,stmt.label)
elseif isa(stmt,Expr)
hd = stmt.head
Expand Down
1 change: 1 addition & 0 deletions base/serialize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let i = 2
DataType, UnionType, Function,
Tuple, Array, Expr, LongSymbol, LongTuple, LongExpr,
LineNumberNode, SymbolNode, LabelNode, GotoNode,
SymbolicLabelNode, SymbolicGotoNode,
QuoteNode, TopNode, TypeVar, Box, LambdaStaticData,
Module, UndefRefTag, Task, :reserved4,
:reserved5, :reserved6, :reserved7, :reserved8,
Expand Down
12 changes: 7 additions & 5 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ show_unquoted(io::IO, x, indent) = (print(io,"\$("); show(io,x); print(io,')'))
## Quoted AST printing ##

typealias ExprNode Union(SymbolNode, LineNumberNode, LabelNode, GotoNode,
TopNode, QuoteNode)
SymbolicLabelNode, SymbolicGotoNode, TopNode, QuoteNode)
show(io::IO, ex::ExprNode) = show_indented(io, ex)

function show_indented(io::IO, ex::ExprNode, indent::Int)
Expand Down Expand Up @@ -378,10 +378,12 @@ end

show_unquoted(io::IO, ex::ExprNode, indent::Int) = show_unquoted(io, ex)

show_unquoted(io::IO, ex::LineNumberNode) = show_linenumber(io, ex.line)
show_unquoted(io::IO, ex::LabelNode) = print(io, ex.label, ": ")
show_unquoted(io::IO, ex::GotoNode) = print(io, "goto ", ex.label)
show_unquoted(io::IO, ex::TopNode) = print(io, "top(", ex.name, ')')
show_unquoted(io::IO, ex::LineNumberNode) = show_linenumber(io, ex.line)
show_unquoted(io::IO, ex::LabelNode) = print(io, ex.label, ": ")
show_unquoted(io::IO, ex::GotoNode) = print(io, "goto ", ex.label)
show_unquoted(io::IO, ex::SymbolicLabelNode) = print(io, ex.label, ": ")
show_unquoted(io::IO, ex::SymbolicGotoNode) = print(io, "goto ", ex.label)
show_unquoted(io::IO, ex::TopNode) = print(io, "top(", ex.name, ')')
show_unquoted(io::IO, ex::QuoteNode, ind::Int) = show_indented(io,ex.value,ind)
function show_unquoted(io::IO, ex::SymbolNode)
print(io, ex.name)
Expand Down
3 changes: 3 additions & 0 deletions src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ jl_datatype_t *jl_getfieldnode_type;
jl_datatype_t *jl_linenumbernode_type;
jl_datatype_t *jl_labelnode_type;
jl_datatype_t *jl_gotonode_type;
jl_datatype_t *jl_symboliclabelnode_type;
jl_datatype_t *jl_symbolicgotonode_type;
jl_datatype_t *jl_quotenode_type;
jl_datatype_t *jl_newvarnode_type;
jl_datatype_t *jl_topnode_type;
Expand Down Expand Up @@ -72,6 +74,7 @@ jl_sym_t *line_sym; jl_sym_t *jl_incomplete_sym;
// head symbols for each expression type
jl_sym_t *goto_sym; jl_sym_t *goto_ifnot_sym;
jl_sym_t *label_sym; jl_sym_t *return_sym;
jl_sym_t *symboliclabel_sym; jl_sym_t *symbolicgoto_sym;
jl_sym_t *lambda_sym; jl_sym_t *assign_sym;
jl_sym_t *null_sym; jl_sym_t *body_sym;
jl_sym_t *macro_sym; jl_sym_t *method_sym;
Expand Down
6 changes: 6 additions & 0 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,12 @@ static value_t julia_to_scm(jl_value_t *v)
if (jl_typeis(v, jl_gotonode_type)) {
return julia_to_list2((jl_value_t*)goto_sym, jl_fieldref(v,0));
}
if (jl_typeis(v, jl_symboliclabelnode_type)) {
return julia_to_list2((jl_value_t*)symboliclabel_sym, jl_fieldref(v,0));
}
if (jl_typeis(v, jl_symbolicgotonode_type)) {
return julia_to_list2((jl_value_t*)symbolicgoto_sym, jl_fieldref(v,0));
}
if (jl_typeis(v, jl_quotenode_type)) {
return julia_to_list2((jl_value_t*)quote_sym, jl_fieldref(v,0));
}
Expand Down
8 changes: 8 additions & 0 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,8 @@ void jl_init_primitives(void)
add_builtin("LineNumberNode", (jl_value_t*)jl_linenumbernode_type);
add_builtin("LabelNode", (jl_value_t*)jl_labelnode_type);
add_builtin("GotoNode", (jl_value_t*)jl_gotonode_type);
add_builtin("SymbolicLabelNode", (jl_value_t*)jl_symboliclabelnode_type);
add_builtin("SymbolicGotoNode", (jl_value_t*)jl_symbolicgotonode_type);
add_builtin("QuoteNode", (jl_value_t*)jl_quotenode_type);
add_builtin("TopNode", (jl_value_t*)jl_topnode_type);
add_builtin("NewvarNode", (jl_value_t*)jl_newvarnode_type);
Expand Down Expand Up @@ -1202,6 +1204,12 @@ DLLEXPORT size_t jl_static_show(JL_STREAM *out, jl_value_t *v)
else if (jl_is_gotonode(v)) {
n += JL_PRINTF(out, "goto %d", jl_gotonode_label(v));
}
else if (jl_is_symboliclabelnode(v)) {
n += JL_PRINTF(out, "%s:", jl_symboliclabelnode_label(v)->name);
}
else if (jl_is_symbolicgotonode(v)) {
n += JL_PRINTF(out, "goto %s", jl_symbolicgotonode_label(v)->name);
}
else if (jl_is_quotenode(v)) {
n += JL_PRINTF(out, "quote ");
n += jl_static_show(out, jl_fieldref(v,0));
Expand Down
15 changes: 8 additions & 7 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ static int is_ast_node(jl_value_t *v)
jl_is_uniontype(v) || jl_is_int32(v) || jl_is_int64(v) ||
jl_is_symbolnode(v) || jl_is_bool(v) || jl_is_typevar(v) ||
jl_is_topnode(v) || jl_is_quotenode(v) || jl_is_gotonode(v) ||
jl_is_labelnode(v) || jl_is_linenode(v) || jl_is_getfieldnode(v);
jl_is_labelnode(v) || jl_is_linenode(v) || jl_is_symboliclabelnode(v) ||
jl_is_symbolicgotonode(v) || jl_is_getfieldnode(v);
}

static int literal_val_id(jl_value_t *v)
Expand Down Expand Up @@ -1211,8 +1212,7 @@ void jl_init_serializer(void)
jl_box_int32(48), jl_box_int32(49), jl_box_int32(50),
jl_box_int32(51), jl_box_int32(52), jl_box_int32(53),
jl_box_int32(54), jl_box_int32(55), jl_box_int32(56),
jl_box_int32(57), jl_box_int32(58), jl_box_int32(59),
jl_box_int32(60), jl_box_int32(61),
jl_box_int32(57),
#endif
jl_box_int64(0), jl_box_int64(1), jl_box_int64(2),
jl_box_int64(3), jl_box_int64(4), jl_box_int64(5),
Expand All @@ -1234,11 +1234,11 @@ void jl_init_serializer(void)
jl_box_int64(48), jl_box_int64(49), jl_box_int64(50),
jl_box_int64(51), jl_box_int64(52), jl_box_int64(53),
jl_box_int64(54), jl_box_int64(55), jl_box_int64(56),
jl_box_int64(57), jl_box_int64(58), jl_box_int64(59),
jl_box_int64(60), jl_box_int64(61),
jl_box_int64(57),
#endif
jl_labelnode_type, jl_linenumbernode_type,
jl_gotonode_type, jl_quotenode_type, jl_topnode_type,
jl_gotonode_type, jl_symboliclabelnode_type,
jl_symbolicgotonode_type, jl_quotenode_type, jl_topnode_type,
jl_type_type, jl_bottom_type, jl_pointer_type,
jl_vararg_type, jl_ntuple_type, jl_abstractarray_type,
jl_storedarray_type, jl_densearray_type, jl_box_type,
Expand All @@ -1258,7 +1258,8 @@ void jl_init_serializer(void)
jl_function_type->name, jl_typector_type->name,
jl_intrinsic_type->name, jl_undef_type->name, jl_task_type->name,
jl_labelnode_type->name, jl_linenumbernode_type->name,
jl_gotonode_type->name, jl_quotenode_type->name,
jl_gotonode_type->name, jl_symboliclabelnode_type->name,
jl_symbolicgotonode_type->name, jl_quotenode_type->name,
jl_topnode_type->name,

jl_root_task, jl_bottom_func,
Expand Down
16 changes: 16 additions & 0 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2760,6 +2760,18 @@ void jl_init_types(void)
jl_tuple(1, jl_long_type), 0, 0);
jl_gotonode_type->fptr = jl_f_default_ctor_1;

jl_symboliclabelnode_type =
jl_new_datatype(jl_symbol("SymbolicLabelNode"), jl_any_type, jl_null,
jl_tuple(1, jl_symbol("label")),
jl_tuple(1, jl_sym_type), 0, 0);
jl_symboliclabelnode_type->fptr = jl_f_default_ctor_1;

jl_symbolicgotonode_type =
jl_new_datatype(jl_symbol("SymbolicGotoNode"), jl_any_type, jl_null,
jl_tuple(1, jl_symbol("label")),
jl_tuple(1, jl_sym_type), 0, 0);
jl_symbolicgotonode_type->fptr = jl_f_default_ctor_1;

jl_quotenode_type =
jl_new_datatype(jl_symbol("QuoteNode"), jl_any_type, jl_null,
jl_tuple(1, jl_symbol("value")),
Expand Down Expand Up @@ -2881,6 +2893,8 @@ void jl_init_types(void)
jl_compute_field_offsets(jl_linenumbernode_type);
jl_compute_field_offsets(jl_labelnode_type);
jl_compute_field_offsets(jl_gotonode_type);
jl_compute_field_offsets(jl_symboliclabelnode_type);
jl_compute_field_offsets(jl_symbolicgotonode_type);
jl_compute_field_offsets(jl_quotenode_type);
jl_compute_field_offsets(jl_topnode_type);
jl_compute_field_offsets(jl_module_type);
Expand All @@ -2900,6 +2914,8 @@ void jl_init_types(void)
goto_sym = jl_symbol("goto");
goto_ifnot_sym = jl_symbol("gotoifnot");
label_sym = jl_symbol("label");
symboliclabel_sym = jl_symbol("symboliclabel");
symbolicgoto_sym = jl_symbol("symbolicgoto");
return_sym = jl_symbol("return");
lambda_sym = jl_symbol("lambda");
macro_sym = jl_symbol("macro");
Expand Down
13 changes: 13 additions & 0 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -2942,6 +2942,19 @@ So far only the second case can actually occur.
(let ((l (make&mark-label)))
(set! label-map
(cons (cons (cadr e) l) label-map))))))
((symboliclabel) (let ((m (assq (cadr e) label-map)))
(if m
(emit `(label ,(cdr m)))
(let ((l (make&mark-label)))
(set! label-map
(cons (cons (cadr e) l) label-map))))))
((symbolicgoto) (let ((m (assq (cadr e) label-map)))
(if m
(emit `(goto ,(cdr m)))
(let ((l (make-label)))
(set! label-map
(cons (cons (cadr e) l) label-map))
(emit `(goto ,l))))))
((type_goto) (let ((m (assq (cadr e) label-map)))
(if m
(emit `(type_goto ,(cdr m) ,@(cddr e)))
Expand Down
7 changes: 7 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ extern jl_datatype_t *jl_getfieldnode_type;
extern jl_datatype_t *jl_linenumbernode_type;
extern jl_datatype_t *jl_labelnode_type;
extern jl_datatype_t *jl_gotonode_type;
extern jl_datatype_t *jl_symboliclabelnode_type;
extern jl_datatype_t *jl_symbolicgotonode_type;
extern jl_datatype_t *jl_quotenode_type;
extern jl_datatype_t *jl_newvarnode_type;
extern jl_datatype_t *jl_topnode_type;
Expand Down Expand Up @@ -413,6 +415,7 @@ extern jl_sym_t *export_sym; extern jl_sym_t *import_sym;
extern jl_sym_t *importall_sym; extern jl_sym_t *using_sym;
extern jl_sym_t *goto_sym; extern jl_sym_t *goto_ifnot_sym;
extern jl_sym_t *label_sym; extern jl_sym_t *return_sym;
extern jl_sym_t *symboliclabel_sym; extern jl_sym_t *symbolicgoto_sym;
extern jl_sym_t *lambda_sym; extern jl_sym_t *assign_sym;
extern jl_sym_t *null_sym; extern jl_sym_t *body_sym;
extern jl_sym_t *macro_sym; extern jl_sym_t *method_sym;
Expand Down Expand Up @@ -461,6 +464,8 @@ extern jl_sym_t *boundscheck_sym; extern jl_sym_t *copyast_sym;
#define jl_linenode_line(x) (((ptrint_t*)x)[1])
#define jl_labelnode_label(x) (((ptrint_t*)x)[1])
#define jl_gotonode_label(x) (((ptrint_t*)x)[1])
#define jl_symboliclabelnode_label(x) ((jl_sym_t*)jl_fieldref(x,1))
#define jl_symbolicgotonode_label(x) ((jl_sym_t*)jl_fieldref(x,1))
#define jl_getfieldnode_val(s) (jl_fieldref(s,0))
#define jl_getfieldnode_name(s) ((jl_sym_t*)jl_fieldref(s,1))
#define jl_getfieldnode_type(s) (jl_fieldref(s,2))
Expand Down Expand Up @@ -513,6 +518,8 @@ extern jl_sym_t *boundscheck_sym; extern jl_sym_t *copyast_sym;
#define jl_is_getfieldnode(v) jl_typeis(v,jl_getfieldnode_type)
#define jl_is_labelnode(v) jl_typeis(v,jl_labelnode_type)
#define jl_is_gotonode(v) jl_typeis(v,jl_gotonode_type)
#define jl_is_symboliclabelnode(v) jl_typeis(v,jl_symboliclabelnode_type)
#define jl_is_symbolicgotonode(v) jl_typeis(v,jl_symbolicgotonode_type)
#define jl_is_quotenode(v) jl_typeis(v,jl_quotenode_type)
#define jl_is_newvarnode(v) jl_typeis(v,jl_newvarnode_type)
#define jl_is_topnode(v) jl_typeis(v,jl_topnode_type)
Expand Down
4 changes: 2 additions & 2 deletions test/remote.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Check that serializer hasn't gone out-of-frame
@test Base.ser_tag[Symbol] == 2
@test Base.ser_tag[()] == 47
@test Base.ser_tag[false] == 123
@test Base.ser_tag[()] == 49
@test Base.ser_tag[false] == 125

# issue #1770
let
Expand Down

0 comments on commit 6e5ce3c

Please sign in to comment.