Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rename expression heads for type definitions to match keywords #23157

Merged
merged 1 commit into from
Aug 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ Language changes
* Nested `if` expressions that arise from the keyword `elseif` now use `elseif`
as their expression head instead of `if` ([#21774]).

* Parsed and lowered forms of type definitions have been synchronized with their
new keywords ([#23157]). Expression heads are renamed as follows:

+ `type` => `struct`

+ `bitstype` => `primitive` (order of arguments is also reversed, to match syntax)

+ `composite_type` => `struct_type`

+ `bits_type` => `primitive_type`

Breaking changes
----------------

Expand Down
12 changes: 6 additions & 6 deletions base/docs/Docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ function nameof(x::Expr, ismacro)
if isexpr(x, :.)
ismacro ? macroname(x) : x
else
n = isexpr(x, (:module, :type, :bitstype)) ? 2 : 1
n = isexpr(x, (:module, :struct)) ? 2 : 1
nameof(x.args[n], ismacro)
end
end
Expand Down Expand Up @@ -505,7 +505,7 @@ function metadata(__source__, __module__, expr, ismodule)
else
push!(args, Pair(:module, __module__))
end
if isexpr(expr, :type)
if isexpr(expr, :struct)
# Field docs for concrete types.
fields = []
tmp = nothing
Expand Down Expand Up @@ -685,11 +685,11 @@ function docm(source::LineNumberNode, mod::Module, meta, ex, define = true)

# Type definitions.
#
# type T ... end
# abstract T
# bitstype N T
# struct T ... end
# abstract type T end
# primitive type T N end
#
isexpr(x, [:type, :abstract, :bitstype]) ? objectdoc(source, mod, meta, def, x) :
isexpr(x, [:struct, :abstract, :primitive]) ? objectdoc(source, mod, meta, def, x) :

# "Bindings". Names that resolve to objects with different names, ie.
#
Expand Down
6 changes: 3 additions & 3 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -901,13 +901,13 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int)
print(io, "end")

# type declaration
elseif head === :type && nargs==3
elseif head === :struct && nargs==3
show_block(io, args[1] ? Symbol("mutable struct") : Symbol("struct"), args[2], args[3], indent)
print(io, "end")

elseif head === :bitstype && nargs == 2
elseif head === :primitive && nargs == 2
print(io, "primitive type ")
show_list(io, reverse(args), ' ', indent)
show_list(io, args, ' ', indent)
print(io, " end")

elseif head === :abstract && nargs == 1
Expand Down
4 changes: 2 additions & 2 deletions doc/src/devdocs/ast.md
Original file line number Diff line number Diff line change
Expand Up @@ -516,8 +516,8 @@ end
parses as:

```
(type true (curly Foo (<: T S))
(block (line 2) (:: x T)))
(struct true (curly Foo (<: T S))
(block (line 2) (:: x T)))
```

The first argument is a boolean telling whether the type is mutable.
Expand Down
2 changes: 1 addition & 1 deletion doc/src/devdocs/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ The front end generates type declarations for all closures. Initially, this was
generating normal type declarations. However, this produced an extremely large number of constructors,
all of which were trivial (simply passing all arguments through to `new`). Since methods are partially
ordered, inserting all of these methods is O(n^2), plus there are just too many of them to keep
around. This was optimized by generating `composite_type` expressions directly (bypassing default
around. This was optimized by generating `struct_type` expressions directly (bypassing default
constructor generation), and using `new` directly to create closure instances. Not the prettiest
thing ever, but you do what you gotta do.

Expand Down
8 changes: 4 additions & 4 deletions doc/src/devdocs/init.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ type description objects for the [built-in types defined in `julia.h`](https://g
e.g.

```c
jl_any_type = jl_new_abstracttype(jl_symbol("Any"), NULL, jl_null);
jl_any_type = jl_new_abstracttype(jl_symbol("Any"), core, NULL, jl_emptysvec);
jl_any_type->super = jl_any_type;

jl_type_type = jl_new_abstracttype(jl_symbol("Type"), jl_any_type, jl_null);
jl_type_type = jl_new_abstracttype(jl_symbol("Type"), core, jl_any_type, jl_emptysvec);

jl_int32_type = jl_new_bitstype(jl_symbol("Int32"),
jl_any_type, jl_null, 32);
jl_int32_type = jl_new_primitivetype(jl_symbol("Int32"), core,
jl_any_type, jl_emptysvec, 32);
```

[`jl_init_tasks()`](https://github.com/JuliaLang/julia/blob/master/src/task.c) creates the `jl_datatype_t* jl_task_type`
Expand Down
8 changes: 4 additions & 4 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ jl_sym_t *exc_sym; jl_sym_t *error_sym;
jl_sym_t *new_sym; jl_sym_t *using_sym;
jl_sym_t *const_sym; jl_sym_t *thunk_sym;
jl_sym_t *anonymous_sym; jl_sym_t *underscore_sym;
jl_sym_t *abstracttype_sym; jl_sym_t *bitstype_sym;
jl_sym_t *compositetype_sym; jl_sym_t *foreigncall_sym;
jl_sym_t *abstracttype_sym; jl_sym_t *primtype_sym;
jl_sym_t *structtype_sym; jl_sym_t *foreigncall_sym;
jl_sym_t *global_sym; jl_sym_t *list_sym;
jl_sym_t *dot_sym; jl_sym_t *newvar_sym;
jl_sym_t *boundscheck_sym; jl_sym_t *inbounds_sym;
Expand Down Expand Up @@ -414,8 +414,8 @@ void jl_init_frontend(void)
underscore_sym = jl_symbol("_");
amp_sym = jl_symbol("&");
abstracttype_sym = jl_symbol("abstract_type");
bitstype_sym = jl_symbol("bits_type");
compositetype_sym = jl_symbol("composite_type");
primtype_sym = jl_symbol("primitive_type");
structtype_sym = jl_symbol("struct_type");
toplevel_sym = jl_symbol("toplevel");
dot_sym = jl_symbol(".");
boundscheck_sym = jl_symbol("boundscheck");
Expand Down
2 changes: 1 addition & 1 deletion src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ JL_CALLABLE(jl_f_svec)
return (jl_value_t*)t;
}

// composite types ------------------------------------------------------------
// struct operations ------------------------------------------------------------

JL_CALLABLE(jl_f_getfield)
{
Expand Down
4 changes: 2 additions & 2 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3859,8 +3859,8 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr)
ctx.builder.CreateCall(prepare_call(jltopeval_func), args);
return ghostValue(jl_void_type);
}
if (head == abstracttype_sym || head == compositetype_sym ||
head == bitstype_sym) {
if (head == abstracttype_sym || head == structtype_sym ||
head == primtype_sym) {
jl_errorf("type definition not allowed inside a local scope");
}
else {
Expand Down
4 changes: 2 additions & 2 deletions src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ static jl_value_t *eval(jl_value_t *e, interpreter_state *s)
JL_GC_POP();
return (jl_value_t*)jl_nothing;
}
else if (ex->head == bitstype_sym) {
else if (ex->head == primtype_sym) {
if (inside_typedef)
jl_error("cannot eval a new bits type definition while defining another type");
jl_value_t *name = args[0];
Expand Down Expand Up @@ -439,7 +439,7 @@ static jl_value_t *eval(jl_value_t *e, interpreter_state *s)
JL_GC_POP();
return (jl_value_t*)jl_nothing;
}
else if (ex->head == compositetype_sym) {
else if (ex->head == structtype_sym) {
if (inside_typedef)
jl_error("cannot eval a new data type definition while defining another type");
jl_value_t *name = args[0];
Expand Down
6 changes: 3 additions & 3 deletions src/julia-parser.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,7 @@
(if (reserved-word? (peek-token s))
(error (string "invalid type name \"" (take-token s) "\"")))
(let ((sig (parse-subtype-spec s)))
(begin0 (list 'type (if mut? 'true 'false) sig (parse-block s))
(begin0 (list 'struct (if mut? 'true 'false) sig (parse-block s))
(expect-end s word))))

;; consume any number of line endings from a token stream
Expand Down Expand Up @@ -1400,7 +1400,7 @@
(begin (take-token s)
(let* ((spec (with-space-sensitive (parse-subtype-spec s)))
(nb (with-space-sensitive (parse-cond s))))
(begin0 (list 'bitstype nb spec)
(begin0 (list 'primitive spec nb)
(expect-end (take-lineendings s) "primitive type"))))))
;; deprecated type keywords
((type)
Expand All @@ -1414,7 +1414,7 @@
(spec (parse-subtype-spec s)))
(syntax-deprecation s (string "bitstype " (deparse nb) " " (deparse spec))
(string "primitive type " (deparse spec) " " (deparse nb) " end"))
(list 'bitstype nb spec)))
(list 'primitive spec nb)))
((typealias)
(let ((lhs (with-space-sensitive (parse-call s)))
(rhs (parse-where s parse-call)))
Expand Down
76 changes: 42 additions & 34 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -887,9 +887,9 @@
(global ,name) (const ,name)
,@(map (lambda (v) `(local ,v)) params)
,@(map (lambda (n v) (make-assignment n (bounds-to-TypeVar v))) params bounds)
(composite_type ,name (call (core svec) ,@params)
(call (core svec) ,@(map (lambda (x) `',x) field-names))
,super (call (core svec) ,@field-types) ,mut ,min-initialized)))
(struct_type ,name (call (core svec) ,@params)
(call (core svec) ,@(map (lambda (x) `',x) field-names))
,super (call (core svec) ,@field-types) ,mut ,min-initialized)))
;; "inner" constructors
(scope-block
(block
Expand Down Expand Up @@ -925,7 +925,7 @@
,@(map (lambda (n v) (make-assignment n (bounds-to-TypeVar v))) params bounds)
(abstract_type ,name (call (core svec) ,@params) ,super))))))

(define (bits-def-expr n name params super)
(define (primitive-type-def-expr n name params super)
(receive
(params bounds) (sparam-name-bounds params)
`(block
Expand All @@ -934,7 +934,7 @@
(block
,@(map (lambda (v) `(local ,v)) params)
,@(map (lambda (n v) (make-assignment n (bounds-to-TypeVar v))) params bounds)
(bits_type ,name (call (core svec) ,@params) ,n ,super))))))
(primitive_type ,name (call (core svec) ,@params) ,n ,super))))))

;; take apart a type signature, e.g. T{X} <: S{Y}
(define (analyze-type-sig ex)
Expand Down Expand Up @@ -1188,7 +1188,7 @@
(else
(error "invalid macro definition"))))

(define (expand-type-def e)
(define (expand-struct-def e)
(let ((mut (cadr e))
(sig (caddr e))
(fields (cdr (cadddr e))))
Expand Down Expand Up @@ -1892,7 +1892,11 @@
'-> expand-arrow
'let expand-let
'macro expand-macro-def
'type expand-type-def
'struct expand-struct-def
'type
(lambda (e)
(syntax-deprecation #f ":type expression head" ":struct")
(expand-struct-def e))
'try expand-try
;; deprecated in 0.6
'typealias (lambda (e) (expand-typealias (cadr e) (caddr e)))
Expand Down Expand Up @@ -2084,11 +2088,15 @@

'bitstype
(lambda (e)
(let ((n (cadr e))
(sig (caddr e)))
(syntax-deprecation #f "Expr(:bitstype, nbits, name)" "Expr(:primitive, name, nbits)")
(expand-forms `(primitive ,(caddr e) ,(cadr e))))
'primitive
(lambda (e)
(let ((sig (cadr e))
(n (caddr e)))
(expand-forms
(receive (name params super) (analyze-type-sig sig)
(bits-def-expr n name params super)))))
(primitive-type-def-expr n name params super)))))

'comparison
(lambda (e) (expand-forms (expand-compare-chain (cdr e))))
Expand Down Expand Up @@ -2781,21 +2789,21 @@ f(x) = yt(x)
(() () 0 ())
(body (global ,name) (const ,name)
,@(map (lambda (p n) `(= ,p (call (core TypeVar) ',n (core Any)))) P names)
(composite_type ,name (call (core svec) ,@P)
(call (core svec) ,@(map (lambda (v) `',v) fields))
,super
(call (core svec) ,@types) false ,(length fields))
(struct_type ,name (call (core svec) ,@P)
(call (core svec) ,@(map (lambda (v) `',v) fields))
,super
(call (core svec) ,@types) false ,(length fields))
(return (null))))))))

(define (type-for-closure name fields super)
`((thunk (lambda ()
(() () 0 ())
(body (global ,name) (const ,name)
(composite_type ,name (call (core svec))
(call (core svec) ,@(map (lambda (v) `',v) fields))
,super
(call (core svec) ,@(map (lambda (v) '(core Any)) fields))
false ,(length fields))
(struct_type ,name (call (core svec))
(call (core svec) ,@(map (lambda (v) `',v) fields))
,super
(call (core svec) ,@(map (lambda (v) '(core Any)) fields))
false ,(length fields))
(return (null)))))))


Expand All @@ -2808,20 +2816,20 @@ f(x) = yt(x)
; `((global ,name)
; (const ,name)
; ,@(map (lambda (p n) `(= ,p (call (core TypeVar) ',n (core Any)))) P names)
; (composite_type ,name (call (core svec) ,@P)
; (call (core svec) ,@(map (lambda (v) `',v) fields))
; ,super
; (call (core svec) ,@types) false ,(length fields)))))
; (struct_type ,name (call (core svec) ,@P)
; (call (core svec) ,@(map (lambda (v) `',v) fields))
; ,super
; (call (core svec) ,@types) false ,(length fields)))))

;; ... and without parameters
;(define (type-for-closure name fields super)
; `((global ,name)
; (const ,name)
; (composite_type ,name (call (core svec))
; (call (core svec) ,@(map (lambda (v) `',v) fields))
; ,super
; (call (core svec) ,@(map (lambda (v) 'Any) fields))
; false ,(length fields))))
; (struct_type ,name (call (core svec))
; (call (core svec) ,@(map (lambda (v) `',v) fields))
; ,super
; (call (core svec) ,@(map (lambda (v) 'Any) fields))
; false ,(length fields))))


(define (vinfo:not-capt vi)
Expand Down Expand Up @@ -3634,25 +3642,25 @@ f(x) = yt(x)
((isdefined) (if tail (emit-return e) e))

;; top level expressions returning values
((abstract_type bits_type composite_type thunk toplevel module)
((abstract_type primitive_type struct_type thunk toplevel module)
(case (car e)
((abstract_type)
(let* ((para (compile (caddr e) break-labels #t #f))
(supe (compile (cadddr e) break-labels #t #f)))
(emit `(abstract_type ,(cadr e) ,para ,supe))))
((bits_type)
((primitive_type)
(let* ((para (compile (caddr e) break-labels #t #f))
(supe (compile (list-ref e 4) break-labels #t #f)))
(emit `(bits_type ,(cadr e) ,para ,(cadddr e) ,supe))))
((composite_type)
(emit `(primitive_type ,(cadr e) ,para ,(cadddr e) ,supe))))
((struct_type)
(let* ((para (compile (caddr e) break-labels #t #f))
(supe (compile (list-ref e 4) break-labels #t #f))
;; composite_type has an unconventional evaluation rule that
;; struct_type has an unconventional evaluation rule that
;; needs to do work around the evaluation of the field types,
;; so the field type expressions need to be kept in place as
;; much as possible. (part of issue #21923)
(ftys (compile (list-ref e 5) break-labels #t #f #f)))
(emit `(composite_type ,(cadr e) ,para ,(cadddr e) ,supe ,ftys ,@(list-tail e 6)))))
(emit `(struct_type ,(cadr e) ,para ,(cadddr e) ,supe ,ftys ,@(list-tail e 6)))))
(else
(emit e)))
(if tail (emit-return '(null)))
Expand Down
4 changes: 2 additions & 2 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -986,8 +986,8 @@ extern jl_sym_t *exc_sym; extern jl_sym_t *new_sym;
extern jl_sym_t *compiler_temp_sym; extern jl_sym_t *foreigncall_sym;
extern jl_sym_t *const_sym; extern jl_sym_t *thunk_sym;
extern jl_sym_t *anonymous_sym; extern jl_sym_t *underscore_sym;
extern jl_sym_t *abstracttype_sym; extern jl_sym_t *bitstype_sym;
extern jl_sym_t *compositetype_sym;
extern jl_sym_t *abstracttype_sym; extern jl_sym_t *primtype_sym;
extern jl_sym_t *structtype_sym;
extern jl_sym_t *global_sym; extern jl_sym_t *unused_sym;
extern jl_sym_t *boundscheck_sym; extern jl_sym_t *inbounds_sym;
extern jl_sym_t *copyast_sym; extern jl_sym_t *fastmath_sym;
Expand Down
Loading