Skip to content

Commit c469c9a

Browse files
committed
Hook up python converter
1 parent b55da85 commit c469c9a

7 files changed

Lines changed: 99 additions & 37 deletions

File tree

localtypings/pxtarget.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ declare namespace ts.pxtc {
410410
target: CompileTarget;
411411
testMode?: boolean;
412412
sourceFiles?: string[];
413+
generatedFiles?: string[];
413414
jres?: pxt.Map<pxt.JRes>;
414415
hexinfo: HexInfo;
415416
extinfo?: ExtensionInfo;

pxtcompiler/emitter/driver.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ namespace ts.pxtc {
200200
res.outfiles[f.slice(6)] = opts.fileSystem[f]
201201
}
202202

203+
for (let f of opts.generatedFiles || []) {
204+
res.outfiles[f] = opts.fileSystem[f]
205+
}
206+
203207
res.times["all"] = U.now() - startTime;
204208
pxt.tickEvent(`compile`, res.times);
205209
return res

pxtlib/main.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ namespace pxt {
99
export import U = pxtc.Util;
1010
export import Util = pxtc.Util;
1111

12-
1312
export interface TCPIO {
1413
onData: (v: Uint8Array) => void;
1514
onError: (e: Error) => void;
@@ -19,6 +18,9 @@ namespace pxt {
1918
disconnectAsync(): Promise<void>;
2019
}
2120

21+
export type ConversionPass = (mpkg: MainPackage, opts: pxtc.CompileOptions)=>void
22+
export let conversionPasses: ConversionPass[] = []
23+
2224
export let mkTCPSocket: (host: string, port: number) => TCPIO;
2325

2426
let savedAppTarget: TargetBundle;

pxtlib/package.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,8 @@ namespace pxt {
767767
}
768768
}
769769
}
770+
for (let pass of pxt.conversionPasses)
771+
pass(this, opts)
770772
opts.jres = this.getJRes()
771773
opts.useNewFunctions = pxt.appTarget.runtime && pxt.appTarget.runtime.functionsOptions && pxt.appTarget.runtime.functionsOptions.useNewFunctions;
772774
return opts;

pxtpy/ast.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ namespace pxt.py {
106106
kind: "Module";
107107
body: Stmt[];
108108
name?: string;
109-
source?: string[];
110-
comments?: string[];
109+
source: string;
110+
tsFilename: string;
111111
}
112112

113113
export interface ExceptHandler extends AST {
@@ -412,38 +412,34 @@ namespace pxt.py {
412412
}
413413

414414
// the following expression can appear in assignment context
415-
export interface AssignmentExpr extends Expr { }
415+
export interface AssignmentExpr extends Expr {
416+
ctx: expr_context;
417+
}
416418
export interface Attribute extends AssignmentExpr {
417419
kind: "Attribute";
418420
value: Expr;
419421
attr: identifier;
420-
ctx: expr_context;
421422
}
422423
export interface Subscript extends AssignmentExpr {
423424
kind: "Subscript";
424425
value: Expr;
425426
slice: AnySlice;
426-
ctx: expr_context;
427427
}
428428
export interface Starred extends AssignmentExpr {
429429
kind: "Starred";
430430
value: Expr;
431-
ctx: expr_context;
432431
}
433432
export interface Name extends AssignmentExpr {
434433
kind: "Name";
435434
id: identifier;
436-
ctx: expr_context;
437435
isdef?: boolean;
438436
}
439437
export interface List extends AssignmentExpr {
440438
kind: "List";
441439
elts: Expr[];
442-
ctx: expr_context;
443440
}
444441
export interface Tuple extends AssignmentExpr {
445442
kind: "Tuple";
446443
elts: Expr[];
447-
ctx: expr_context;
448444
}
449445
}

pxtpy/converter.ts

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -954,10 +954,6 @@ namespace pxt.py {
954954
return v.kind == "Name" && (v as py.Name).id == "self"
955955
}
956956

957-
function sourceAt(e: py.AST) {
958-
return (ctx.currModule.source[e.lineno - 1] || "").slice(e.col_offset)
959-
}
960-
961957
const exprMap: Map<(v: py.Expr) => B.JsNode> = {
962958
BoolOp: (n: py.BoolOp) => {
963959
let r = expr(n.values[0])
@@ -1258,11 +1254,7 @@ namespace pxt.py {
12581254
},
12591255
Num: (n: py.Num) => {
12601256
unify(n.tsType, tpNumber)
1261-
let src = sourceAt(n)
1262-
let m = /^(0[box][0-9a-f]+)/i.exec(src)
1263-
if (m)
1264-
return B.mkText(m[1])
1265-
return B.mkText(n.n + "")
1257+
return B.mkText(n.ns)
12661258
},
12671259
Str: (n: py.Str) => {
12681260
unify(n.tsType, tpString)
@@ -1355,16 +1347,7 @@ namespace pxt.py {
13551347
U.oops(e.kind + " - unknown stmt")
13561348
}
13571349

1358-
let cmts: string[] = []
1359-
let scmts = ctx.currModule.comments
1360-
if (scmts) {
1361-
for (let i = 0; i < e.lineno; ++i) {
1362-
if (scmts[i]) {
1363-
cmts.push(scmts[i])
1364-
scmts[i] = null
1365-
}
1366-
}
1367-
}
1350+
let cmts: string[] = (e._comments || []).map(c => c.value)
13681351

13691352
let r = f(e)
13701353
if (currErrs) {
@@ -1400,14 +1383,6 @@ namespace pxt.py {
14001383
]
14011384
}
14021385

1403-
function parseComments(mod: py.Module) {
1404-
mod.comments = mod.source.map(l => {
1405-
let m = /(\s|^)#\s*(.*)/.exec(l)
1406-
if (m) return m[2]
1407-
return null
1408-
})
1409-
}
1410-
14111386
function iterPy(e: py.AST, f: (v: py.AST) => void) {
14121387
if (!e) return
14131388
f(e)
@@ -1419,4 +1394,72 @@ namespace pxt.py {
14191394
v.forEach((x: any) => iterPy(x, f))
14201395
})
14211396
}
1397+
1398+
export function convert(mpkg: MainPackage, opts: pxtc.CompileOptions) {
1399+
moduleAst = {}
1400+
1401+
if (!opts.generatedFiles)
1402+
opts.generatedFiles = []
1403+
1404+
for (const pkg of mpkg.sortedDeps()) {
1405+
for (const f of pkg.getFiles()) {
1406+
if (!U.endsWith(f, ".py"))
1407+
continue
1408+
let sn = f
1409+
let modname = f.replace(/^\.py/, "")
1410+
if (pkg.level > 0)
1411+
sn = "pxt_modules/" + pkg.id + "/" + f
1412+
let src = pkg.readFile(f)
1413+
1414+
try {
1415+
let tokens = pxt.py.lex(src)
1416+
console.log(pxt.py.tokensToString(tokens))
1417+
let stmts = pxt.py.parse(src, sn, tokens)
1418+
console.log(pxt.py.dump(stmts))
1419+
1420+
sn += ".ts"
1421+
1422+
moduleAst[modname] = {
1423+
kind: "Module",
1424+
body: stmts,
1425+
name: modname,
1426+
tsFilename: sn
1427+
} as any
1428+
} catch (e) {
1429+
// TODO
1430+
console.log("Parse error", e)
1431+
}
1432+
}
1433+
}
1434+
1435+
for (let i = 0; i < 5; ++i) {
1436+
currIteration = i
1437+
for (let m of U.values(moduleAst)) {
1438+
try {
1439+
toTS(m)
1440+
} catch (e) {
1441+
console.log("Conv pass error", e);
1442+
}
1443+
}
1444+
}
1445+
1446+
let files: pxt.Map<string> = {}
1447+
1448+
currIteration = 1000
1449+
for (let m of U.values(moduleAst)) {
1450+
try {
1451+
let nodes = toTS(m)
1452+
if (!nodes) return
1453+
let res = B.flattenNode(nodes)
1454+
opts.sourceFiles.push(m.tsFilename)
1455+
opts.generatedFiles.push(m.tsFilename)
1456+
opts.fileSystem[m.tsFilename] = res.output
1457+
} catch (e) {
1458+
console.log("Conv error", e);
1459+
}
1460+
}
1461+
}
1462+
1463+
1464+
pxt.conversionPasses.push(convert)
14221465
}

pxtpy/parser.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,16 @@ namespace pxt.py {
568568
function testlist(): Expr { return testlist_core(test) }
569569
function exprlist(): Expr { return testlist_core(expr) }
570570

571+
// somewhat approximate
572+
function setStoreCtx(e: Expr) {
573+
if (e.kind == "Tuple") {
574+
let t = e as Tuple
575+
t.elts.forEach(setStoreCtx)
576+
} else {
577+
(e as AssignmentExpr).ctx = "Store"
578+
}
579+
}
580+
571581
function expr_stmt(): Stmt {
572582
let t0 = peekToken()
573583
let expr = testlist_star_expr()
@@ -587,6 +597,7 @@ namespace pxt.py {
587597
break
588598
}
589599
}
600+
assign.targets.forEach(setStoreCtx)
590601
return finish(assign)
591602
}
592603

@@ -600,6 +611,7 @@ namespace pxt.py {
600611
annAssign.value = test()
601612
}
602613
annAssign.simple = t0.type == TokenType.Id && expr.kind == "Name" ? 1 : 0
614+
setStoreCtx(annAssign.target)
603615
return finish(annAssign)
604616
}
605617

@@ -609,6 +621,7 @@ namespace pxt.py {
609621
augAssign.op = op.replace("Assign", "") as operator
610622
shiftToken()
611623
augAssign.value = testlist()
624+
setStoreCtx(augAssign.target)
612625
return finish(augAssign)
613626
}
614627

@@ -1089,6 +1102,7 @@ namespace pxt.py {
10891102
let r = mkAST("Name") as Name
10901103
shiftToken()
10911104
r.id = t.value
1105+
r.ctx = "Load"
10921106
return finish(r)
10931107
} else if (t.type == TokenType.Number) {
10941108
let r = mkAST("Num") as Num

0 commit comments

Comments
 (0)