Skip to content

Commit

Permalink
refactor resolve-scopes pass (JuliaLang#30656)
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Jan 16, 2019
1 parent f561821 commit b70ad64
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 217 deletions.
22 changes: 1 addition & 21 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ typedef struct _jl_ast_context_t {
jl_ast_context_list_t list;
int ref;
jl_task_t *task; // the current owner (user) of this jl_ast_context_t
jl_module_t *module; // context module for "defined-julia-global" and "current-julia-module-counter"
jl_module_t *module; // context module for `current-julia-module-counter`
} jl_ast_context_t;

static jl_ast_context_t jl_ast_main_ctx;
Expand Down Expand Up @@ -129,25 +129,6 @@ static jl_value_t *scm_to_julia(fl_context_t *fl_ctx, value_t e, jl_module_t *mo
static value_t julia_to_scm(fl_context_t *fl_ctx, jl_value_t *v);
static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, struct macroctx_stack *macroctx, int onelevel);

value_t fl_defined_julia_global(fl_context_t *fl_ctx, value_t *args, uint32_t nargs)
{
jl_ast_context_t *ctx = jl_ast_ctx(fl_ctx);
// tells whether a var is defined in and *by* the current module
argcount(fl_ctx, "defined-julia-global", nargs, 1);
jl_module_t *mod = ctx->module;
jl_sym_t *sym = (jl_sym_t*)scm_to_julia(fl_ctx, args[0], mod);
if (jl_is_globalref(sym)) {
mod = jl_globalref_mod(sym);
sym = jl_globalref_name(sym);
}
if (!jl_is_symbol(sym))
type_error(fl_ctx, "defined-julia-global", "symbol", args[0]);
if (!mod)
return fl_ctx->F;
jl_binding_t *b = (jl_binding_t*)ptrhash_get(&mod->bindings, sym);
return (b != HT_NOTFOUND && b->owner == mod) ? fl_ctx->T : fl_ctx->F;
}

value_t fl_current_module_counter(fl_context_t *fl_ctx, value_t *args, uint32_t nargs)
{
jl_ast_context_t *ctx = jl_ast_ctx(fl_ctx);
Expand Down Expand Up @@ -214,7 +195,6 @@ value_t fl_julia_logmsg(fl_context_t *fl_ctx, value_t *args, uint32_t nargs)
}

static const builtinspec_t julia_flisp_ast_ext[] = {
{ "defined-julia-global", fl_defined_julia_global },
{ "current-julia-module-counter", fl_current_module_counter },
{ "julia-scalar?", fl_julia_scalar },
{ "julia-logmsg", fl_julia_logmsg },
Expand Down
3 changes: 3 additions & 0 deletions src/ast.scm
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@
(define (reset-gensyms)
(set! *current-gensyms* *gensyms*))

(define (some-gensym? x)
(or (gensym? x) (memq x *gensyms*)))

(define make-ssavalue
(let ((ssavalue-counter 0))
(lambda ()
Expand Down
57 changes: 2 additions & 55 deletions src/jlfrontend.scm
Original file line number Diff line number Diff line change
Expand Up @@ -29,72 +29,19 @@
'(error "malformed expression"))))
thk))

;; assigned variables except those marked local or inside inner functions
(define (find-possible-globals- e tab)
(cond ((atom? e) tab)
((quoted? e) tab)
(else (case (car e)
((=) (if (not (ssavalue? (cadr e)))
(put! tab (decl-var (cadr e)) #t))
(find-possible-globals- (caddr e) tab))
((method) (let ((n (method-expr-name e)))
(if (symbol? n)
(put! tab n #t)
tab)))
((lambda) tab)
((local) tab)
((scope-block)
;; TODO: when deprecation for implicit global assignment inside loops
;; is removed, remove this code and just return `tab` in this case
(let ((tab2 (table)))
(find-possible-globals- (cadr e) tab2)
(for-each (lambda (v) (if (has? tab2 v) (del! tab2 v)))
(append (find-local-decls (cadr e)) (find-local-def-decls (cadr e))))
(for-each (lambda (v) (put! tab v #t))
(table.keys tab2))))
((break-block) (find-possible-globals- (caddr e) tab))
((module toplevel) '())
(else
(for-each (lambda (x) (find-possible-globals- x tab))
(cdr e))))
tab)))

;; find variables that should be forced to be global in a toplevel expr
(define (find-possible-globals e)
(table.keys (find-possible-globals- e (table))))

;; this is overwritten when we run in actual julia
(define (defined-julia-global v) #f)

(define (some-gensym? x)
(or (gensym? x) (memq x *gensyms*)))


;; return a lambda expression representing a thunk for a top-level expression
;; note: expansion of stuff inside module is delayed, so the contents obey
;; toplevel expansion order (don't expand until stuff before is evaluated).
(define (expand-toplevel-expr-- e file line)
(let ((ex0 (julia-expand-macroscope e)))
(if (and (pair? ex0) (eq? (car ex0) 'toplevel))
(if (toplevel-only-expr? ex0)
ex0
(let* ((ex (julia-expand0 ex0))
(lv (find-decls 'local ex))
(gv (diff (delete-duplicates
(append (find-decls 'const ex) ;; convert vars declared const outside any scope block to outer-globals
(find-decls 'global ex) ;; convert vars declared global outside any scope block to outer-globals
;; vars assigned at the outer level
(filter (lambda (x) (not (some-gensym? x)))
(find-assigned-vars ex '()))))
lv))
;; vars assigned anywhere, if they have not been explicitly defined
(existing-gv (filter (lambda (x) (and (not (or (memq x lv) (memq x gv))) (defined-julia-global x)))
(find-possible-globals ex)))
(th (julia-expand1
`(lambda () ()
(scope-block
(block ,@(map (lambda (v) `(implicit-global ,v)) existing-gv)
,@(map (lambda (v) `(implicit-global ,v)) gv)
,ex)))
,(blockify ex)))
file line)))
(if (and (null? (cdadr (caddr th)))
(and (length= (lam:body th) 2)
Expand Down
Loading

0 comments on commit b70ad64

Please sign in to comment.