Skip to content
This repository was archived by the owner on Dec 8, 2025. It is now read-only.

Commit ab3d636

Browse files
committed
fix bool/string literals; add tests
1 parent 2d41608 commit ab3d636

3 files changed

Lines changed: 64 additions & 14 deletions

File tree

compiler/src/compiler.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -862,13 +862,22 @@ class Program implements TopOpWriter {
862862
}
863863
}
864864

865+
private valueIsAlwaysFalse(v: Value) {
866+
if (v.isLiteral) return v.numValue == 0
867+
return v.op == Op.EXPR0_FALSE || v.op == Op.EXPR0_NULL
868+
}
869+
870+
private valueIsAlwaysTrue(v: Value) {
871+
if (v.isLiteral) return v.numValue != 0 && !isNaN(v.numValue)
872+
return v.op == Op.EXPR0_TRUE
873+
}
874+
865875
private emitIfStatement(stmt: ts.IfStatement) {
866876
const cond = this.emitSimpleValue(stmt.expression, ValueType.BOOL)
867-
if (cond.isLiteral) {
868-
if (cond.numValue) this.emitStmt(stmt.thenStatement)
869-
else {
870-
if (stmt.elseStatement) this.emitStmt(stmt.elseStatement)
871-
}
877+
if (this.valueIsAlwaysFalse(cond)) {
878+
if (stmt.elseStatement) this.emitStmt(stmt.elseStatement)
879+
} else if (this.valueIsAlwaysTrue(cond)) {
880+
this.emitStmt(stmt.thenStatement)
872881
} else {
873882
this.writer.emitIfAndPop(
874883
cond,
@@ -2489,15 +2498,16 @@ class Program implements TopOpWriter {
24892498
}
24902499

24912500
private emitLiteral(v: any, node?: ts.Node) {
2492-
if (v === true) v = 1
2493-
else if (v === false) v = 0
2494-
2495-
if (v === null || v === undefined) return literal(v)
2501+
if (
2502+
v === null ||
2503+
v === undefined ||
2504+
typeof v == "number" ||
2505+
typeof v == "boolean"
2506+
)
2507+
return literal(v)
24962508

24972509
if (typeof v == "string") return this.writer.emitString(v)
24982510

2499-
if (typeof v == "number") return literal(v)
2500-
25012511
throwError(node, "unhandled literal: " + v)
25022512
}
25032513

@@ -2792,7 +2802,11 @@ class Program implements TopOpWriter {
27922802
let a = this.emitSimpleValue(expr.left, dstTp)
27932803
let b = this.emitSimpleValue(expr.right, dstTp)
27942804
if (swap) [a, b] = [b, a]
2795-
return wr.emitExpr(op2, a, b)
2805+
2806+
const res = wr.emitExpr(op2, a, b)
2807+
if (op2 == Op.EXPR2_ADD && this.isStringLike(expr))
2808+
res.valueType = ValueType.STRING
2809+
return res
27962810
}
27972811

27982812
private emitUnaryExpression(expr: ts.PrefixUnaryExpression): Value {

compiler/src/opwriter.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,19 @@ export class CachedValue {
122122
}
123123
}
124124

125-
export function literal(v: number) {
125+
export function literal(v: number | boolean) {
126126
if (v == null) {
127127
const r = new Value(ValueType.NULL)
128128
r.op = Op.EXPR0_NULL
129129
r.args = []
130130
r.flags = 0
131131
return r
132+
} else if (typeof v == "boolean") {
133+
const r = new Value(ValueType.BOOL)
134+
r.op = v ? Op.EXPR0_TRUE : Op.EXPR0_FALSE
135+
r.args = []
136+
r.flags = 0
137+
return r
132138
} else {
133139
const r = new Value(ValueType.NUMBER)
134140
r.numValue = v
@@ -275,7 +281,9 @@ export class OpWriter {
275281
}
276282

277283
emitString(s: string | Uint8Array) {
278-
const v = new Value(ValueType.BUFFER)
284+
const v = new Value(
285+
typeof s == "string" ? ValueType.STRING : ValueType.BUFFER
286+
)
279287
let idx = 0
280288
if (typeof s == "string") {
281289
idx = this.prog.addString(s)

devs/run-tests/basic.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ function isEq(x: number, y: number): void {
1717
}
1818
}
1919

20+
function strEq(a: string, b: string) {
21+
if (a != b) {
22+
console.log(`fail: '${a}' != '${b}'`)
23+
panic(110)
24+
}
25+
}
26+
2027
let x = 0
2128

2229
function testFlow() {
@@ -245,6 +252,26 @@ function testConsole() {
245252
console.log(`text ${n} + ${q} is`, n + q)
246253
}
247254

255+
function testString() {
256+
strEq("a" + "b", "ab")
257+
strEq("a" + 1, "a1")
258+
strEq(1 + "a", "1a")
259+
strEq(":" + true, ":true")
260+
strEq(":" + false, ":false")
261+
strEq(":" + null, ":null")
262+
strEq(":" + 1.4, ":1.4")
263+
strEq(":" + NaN, ":NaN")
264+
265+
const b = Buffer.alloc(3)
266+
b[0] = 0x42
267+
b[1] = 0x6c
268+
strEq(":" + b, ":[Buffer[3] 426c00]")
269+
270+
strEq(`x${1}`, "x1")
271+
strEq(`x${true}x`, "xtruex")
272+
strEq(`x ${null} x`, "x null x")
273+
}
274+
248275
testFlow()
249276
if (x != 42) panic(10)
250277
testMath()
@@ -253,5 +280,6 @@ testBuffer()
253280
testArray()
254281
testObj()
255282
testConsole()
283+
testString()
256284
console.log("all OK")
257285
ds.reboot()

0 commit comments

Comments
 (0)