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

refactor resolve-scopes pass #30656

Merged
merged 1 commit into from
Jan 16, 2019
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
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