Skip to content

Commit 0050076

Browse files
committed
Remove VarDesc
1 parent 292c249 commit 0050076

3 files changed

Lines changed: 52 additions & 41 deletions

File tree

pxtpy/ast.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace pxt.py {
66
pyType?: Type;
77
}
88

9-
export interface SymbolInfo extends pxtc.SymbolInfo {
9+
export interface SymbolInfo extends pxtc.SymbolInfo, VarDescOptions {
1010
pyRetType?: Type;
1111
pySymbolType?: Type;
1212
pyInstanceType?: Type;
@@ -34,16 +34,9 @@ namespace pxt.py {
3434
isPlainImport?: boolean;
3535
isLocal?: boolean;
3636
isParam?: boolean;
37-
fundef?: py.FunctionDef;
38-
classdef?: py.ClassDef;
3937
isImport?: SymbolInfo;
4038
}
4139

42-
export interface VarDesc extends VarDescOptions {
43-
type: Type;
44-
name: string;
45-
}
46-
4740
// based on grammar at https://docs.python.org/3/library/ast.html
4841
export interface AST {
4942
lineno: number;
@@ -154,7 +147,7 @@ namespace pxt.py {
154147
}
155148

156149
export interface ScopeDef extends Stmt {
157-
vars?: Map<VarDesc>;
150+
vars?: Map<SymbolInfo>;
158151
parent?: ScopeDef;
159152
}
160153

pxtpy/converter.ts

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -216,20 +216,23 @@ namespace pxt.py {
216216
}
217217

218218
function addImport(a: AST, name: string, scope?: ScopeDef) {
219-
const v = defvar(name, { isPlainImport: true }, scope)
220219
const sym = lookupGlobalSymbol(name)
221220
if (!sym)
222221
error(a, U.lf("No module named '{0}'", name))
223-
else
224-
unify(a, v.type, symbolType(sym))
225-
return v
222+
return sym
226223
}
227224

228225
function defvar(n: string, opts: py.VarDescOptions, scope?: ScopeDef) {
229-
let scopeDef = scope || currentScope()
230-
let v = scopeDef.vars[n]
226+
if (!scope)
227+
scope = currentScope()
228+
let v = scope.vars[n]
231229
if (!v) {
232-
v = scopeDef.vars[n] = { type: mkType(), name: n }
230+
let qn = getFullName(scope) + "." + n
231+
if (isLocalScope(scope))
232+
v = mkSymbol(SK.Variable, qn)
233+
else
234+
v = addSymbol(SK.Variable, qn)
235+
scope.vars[n] = v
233236
}
234237
for (let k of Object.keys(opts)) {
235238
(v as any)[k] = (opts as any)[k]
@@ -245,6 +248,7 @@ namespace pxt.py {
245248
return t
246249
}
247250

251+
// TODO cache it?
248252
function getFullName(n: py.AST): string {
249253
let s = n as py.ScopeDef
250254
let pref = ""
@@ -381,29 +385,48 @@ namespace pxt.py {
381385
}
382386
}
383387

384-
function addSymbol(kind: SK, qname: string) {
385-
let sym = internalApis[qname]
386-
if (sym) return sym
388+
function mkSymbol(kind: SK, qname: string): SymbolInfo {
387389
let m = /(.*)\.(.*)/.exec(qname)
388-
sym = {
390+
return {
389391
kind: kind,
390392
name: m ? m[2] : qname,
391393
qName: qname,
392394
namespace: m ? m[1] : "",
393395
attributes: {} as any,
394-
pyRetType: mkType(),
396+
pyRetType: mkType()
395397
} as any
398+
}
399+
400+
function addSymbol(kind: SK, qname: string) {
401+
let sym = internalApis[qname]
402+
if (sym) return sym
403+
sym = mkSymbol(kind, qname)
396404
internalApis[sym.qName] = sym
397405
return sym
398406
}
399407

400-
function addSymbolFor(k: SK, n: py.Symbol) {
408+
function isLocalScope(scope: ScopeDef) {
409+
while (scope) {
410+
if (scope.kind == "FunctionDef")
411+
return true
412+
scope = scope.parent
413+
}
414+
return false
415+
}
416+
417+
function addSymbolFor(k: SK, n: py.Symbol, scope?: ScopeDef) {
401418
if (!n.symInfo) {
402419
let qn = getFullName(n)
403420
if (U.endsWith(qn, ".__init__"))
404421
qn = qn.slice(0, -9) + ".__constructor"
405-
n.symInfo = addSymbol(k, qn)
406-
n.symInfo.pyAST = n
422+
scope = scope || currentScope()
423+
if (isLocalScope(scope))
424+
n.symInfo = mkSymbol(k, qn)
425+
else
426+
n.symInfo = addSymbol(k, qn)
427+
const sym = n.symInfo
428+
sym.pyAST = n
429+
scope.vars[sym.name] = sym
407430
}
408431
return n.symInfo
409432
}
@@ -482,10 +505,9 @@ namespace pxt.py {
482505

483506
function getClassDef(e: py.Expr) {
484507
let n = getName(e)
485-
let v = lookupVar(n)
486-
if (v)
487-
return v.classdef
488-
let s = lookupGlobalSymbol(n)
508+
let s = lookupVar(n)
509+
if (!s)
510+
s = lookupGlobalSymbol(n)
489511
if (s && s.pyAST && s.pyAST.kind == "ClassDef")
490512
return s.pyAST as py.ClassDef
491513
return null
@@ -616,8 +638,8 @@ namespace pxt.py {
616638

617639
let lst = n.symInfo.parameters.map(p => {
618640
let v = defvar(p.name, { isParam: true })
619-
unify(n, v.type, p.pyType)
620-
let res = [quote(p.name), typeAnnot(v.type)]
641+
unify(n, symbolType(v), p.pyType)
642+
let res = [quote(p.name), typeAnnot(p.pyType)]
621643
if (p.default) {
622644
res.push(B.mkText(" = " + p.default))
623645
}
@@ -760,7 +782,7 @@ namespace pxt.py {
760782
if (funname == "__set__" && vv) {
761783
let cf = getClassField(ctx.currClass.symInfo, "__get__")
762784
if (cf.pyAST && cf.pyAST.kind == "FunctionDef")
763-
unify(n, vv.type, cf.pyRetType)
785+
unify(n, vv.pyRetType, cf.pyRetType)
764786
}
765787
funname = funname.replace(/_/g, "")
766788
}
@@ -780,10 +802,8 @@ namespace pxt.py {
780802
doArgs(n, isMethod),
781803
n.returns ? typeAnnot(compileType(n.returns)) : B.mkText(""))
782804

783-
if (!isMethod) {
784-
const v = defvar(n.name, { fundef: n })
785-
unify(n, symbolType(sym), v.type)
786-
}
805+
// make sure type is initialized
806+
symbolType(sym)
787807

788808
let body = n.body.map(stmt)
789809
if (n.name == "__init__") {
@@ -805,9 +825,7 @@ namespace pxt.py {
805825
ClassDef: (n: py.ClassDef) => guardedScope(n, () => {
806826
setupScope(n)
807827

808-
const cv = defvar(n.name, { classdef: n })
809828
const sym = addSymbolFor(SK.Class, n)
810-
unify(n, cv.type, symbolType(sym))
811829

812830
U.assert(!ctx.currClass)
813831
let topLev = isTopLevel()
@@ -1009,7 +1027,7 @@ namespace pxt.py {
10091027
let v = defvar(id, { isLocal: true })
10101028
id = quoteStr(id)
10111029
res.push(B.mkStmt(B.mkText("const " + id + " = "), devRef))
1012-
unifyTypeOf(it.context_expr, v.type)
1030+
unifyTypeOf(it.context_expr, v.pyRetType)
10131031
devRef = B.mkText(id)
10141032
}
10151033
res.push(B.mkStmt(B.mkInfix(devRef, ".", B.mkText("begin()"))))
@@ -1138,7 +1156,7 @@ namespace pxt.py {
11381156
} else {
11391157
n.isdef = false
11401158
}
1141-
unify(n, n.tsType, curr.type)
1159+
unify(n, n.tsType, curr.pyRetType)
11421160
}
11431161

11441162
if (n.isdef)
@@ -1526,7 +1544,7 @@ namespace pxt.py {
15261544

15271545
let v = lookupVar(n.id)
15281546
if (v) {
1529-
unify(n, n.tsType, v.type)
1547+
unify(n, n.tsType, symbolType(v))
15301548
if (v.isImport)
15311549
return quote(n.id) // it's import X = Y.Z.X, use X not Y.Z.X
15321550
} else if (currIteration > 0) {

webapp/src/compiler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export function assembleAsync(src: string) {
123123
}
124124

125125
function compileCoreAsync(opts: pxtc.CompileOptions): Promise<pxtc.CompileResult> {
126-
// we don't want any conversion to be run on the worker sides
126+
// we don't want any conversion to be run on the worker side
127127
opts.target.preferredEditor = pxt.JAVASCRIPT_PROJECT_NAME
128128
return workerOpAsync("compile", { options: opts })
129129
}

0 commit comments

Comments
 (0)