Naive parseFloat

This commit is contained in:
dcodeIO 2018-01-29 07:42:40 +01:00
parent d3f22637ed
commit 9e3b6f202d
7 changed files with 799 additions and 106 deletions

View File

@ -13,7 +13,8 @@ import {
import { import {
Node, Node,
Expression, Expression,
BinaryExpression BinaryExpression,
SourceKind
} from "./ast"; } from "./ast";
import { import {
@ -1539,6 +1540,8 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
compiler.error(DiagnosticCode.Operation_not_supported, reportNode.range); compiler.error(DiagnosticCode.Operation_not_supported, reportNode.range);
return module.createUnreachable(); return module.createUnreachable();
} }
if (reportNode.range.source.sourceKind != SourceKind.STDLIB)
compiler.warning(DiagnosticCode.Operation_is_unsafe, reportNode.range);
return arg0; // any usize to any usize return arg0; // any usize to any usize
case "assert": // assert<T?>(isTrueish: T, message?: string) -> T with T != null (see also assembly.d.ts) case "assert": // assert<T?>(isTrueish: T, message?: string) -> T with T != null (see also assembly.d.ts)

View File

@ -102,6 +102,7 @@ import {
ParenthesizedExpression, ParenthesizedExpression,
PropertyAccessExpression, PropertyAccessExpression,
TernaryExpression, TernaryExpression,
ArrayLiteralExpression,
StringLiteralExpression, StringLiteralExpression,
UnaryPostfixExpression, UnaryPostfixExpression,
UnaryPrefixExpression, UnaryPrefixExpression,
@ -2835,8 +2836,13 @@ export class Compiler extends DiagnosticEmitter {
compileLiteralExpression(expression: LiteralExpression, contextualType: Type): ExpressionRef { compileLiteralExpression(expression: LiteralExpression, contextualType: Type): ExpressionRef {
switch (expression.literalKind) { switch (expression.literalKind) {
// case LiteralKind.ARRAY:
// return this.compileStaticArray(...); case LiteralKind.ARRAY:
var classType = contextualType.classType;
if (classType && classType == this.program.elements.get("Array") && classType.typeArguments && classType.typeArguments.length == 1)
return this.compileStaticArray(classType.typeArguments[0], (<ArrayLiteralExpression>expression).elementExpressions);
this.error(DiagnosticCode.Operation_not_supported, expression.range);
return this.module.createUnreachable();
case LiteralKind.FLOAT: { case LiteralKind.FLOAT: {
var floatValue = (<FloatLiteralExpression>expression).value; var floatValue = (<FloatLiteralExpression>expression).value;
@ -2904,7 +2910,19 @@ export class Compiler extends DiagnosticEmitter {
: this.module.createI32(stringOffset.lo); : this.module.createI32(stringOffset.lo);
} }
compileStaticArray(elementType: Type, expressions: Expression): ExpressionRef { compileStaticArray(elementType: Type, expressions: (Expression | null)[]): ExpressionRef {
// compile as static if all element expressions are precomputable, otherwise
// initialize in place.
var exprs = new Array<ExpressionRef>(expressions.length);
var isStatic = true;
var expr: BinaryenExpressionRef;
for (var i = 0; i < expressions.length; ++i) {
exprs[i] = expressions[i] ? this.compileExpression(<Expression>expressions[i], elementType) : elementType.toNativeZero(this.module);
if (isStatic && _BinaryenExpressionGetId(expr = this.precomputeExpressionRef(exprs[i])) == ExpressionId.Const) {
// TODO: use multiple arrays of possible native types?
} else
isStatic = false;
}
throw new Error("not implemented"); throw new Error("not implemented");
} }

View File

@ -325,6 +325,7 @@ function isWhiteSpaceOrLineTerminator(c: u16): bool {
const enum CharCode { const enum CharCode {
PLUS = 0x2B, PLUS = 0x2B,
MINUS = 0x2D, MINUS = 0x2D,
DOT = 0x2E,
_0 = 0x30, _0 = 0x30,
_1 = 0x31, _1 = 0x31,
_2 = 0x32, _2 = 0x32,
@ -337,11 +338,13 @@ const enum CharCode {
_9 = 0x39, _9 = 0x39,
A = 0x41, A = 0x41,
B = 0x42, B = 0x42,
E = 0x45,
O = 0x4F, O = 0x4F,
X = 0x58, X = 0x58,
Z = 0x5a, Z = 0x5a,
a = 0x61, a = 0x61,
b = 0x62, b = 0x62,
e = 0x65,
o = 0x6F, o = 0x6F,
x = 0x78, x = 0x78,
z = 0x7A z = 0x7A
@ -410,16 +413,62 @@ export function parseInt(str: String, radix: i32 = 0): i64 {
else if (code >= CharCode.a && code <= CharCode.z) else if (code >= CharCode.a && code <= CharCode.z)
code -= CharCode.a - 10; code -= CharCode.a - 10;
else else
return sign * num; break;
if (code >= radix) if (code >= radix)
return sign * num; break;
num = (num * radix) + code; num = (num * radix) + code;
ptr += 2; ptr += 2;
} }
return sign * num; return sign * num;
} }
// @binding(CALL, [ STRING ], PASS_THRU)
export function parseFloat(str: string): f64 { export function parseFloat(str: string): f64 {
throw new Error("not implemented"); var len: i32 = str.length;
if (!len)
return NaN;
var ptr = changetype<usize>(str) /* + HEAD -> offset */;
var code = <i32>load<u16>(ptr, HEAD);
// determine sign
var sign: f64;
if (code == CharCode.MINUS) {
if (!--len)
return NaN;
code = <i32>load<u16>(ptr += 2, HEAD);
sign = -1;
} else if (code == CharCode.PLUS) {
if (!--len)
return NaN;
code = <i32>load<u16>(ptr += 2, HEAD);
sign = 1;
} else
sign = 1;
// calculate value
var num: f64 = 0;
while (len--) {
code = <i32>load<u16>(ptr, HEAD);
if (code == CharCode.DOT) {
ptr += 2;
var fac: f64 = 0.1; // precision :(
while (len--) {
code = <i32>load<u16>(ptr, HEAD);
if (code == CharCode.E || code == CharCode.e)
assert(false); // TODO
code -= CharCode._0;
if (<u32>code > 9)
break;
num += <f64>code * fac;
fac *= 0.1;
ptr += 2;
}
break;
}
code -= CharCode._0;
if (<u32>code >= 10)
break;
num = (num * 10) + code;
ptr += 2;
}
return sign * num;
} }

View File

@ -78,8 +78,8 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
// already covered by instantiate below, which is also able to use imports, but doesn't // already covered by instantiate below, which is also able to use imports, but doesn't
// provide as much debugging information. might be necessary to remove this one once imports // provide as much debugging information. might be necessary to remove this one once imports
// are tested more. // are tested more.
module.interpret(); // module.interpret();
console.log(chalk.green("interpret OK")); // console.log(chalk.green("interpret OK"));
try { try {
var binary = module.toBinary(); var binary = module.toBinary();
var wasmModule = new WebAssembly.Module(binary); var wasmModule = new WebAssembly.Module(binary);

View File

@ -3,6 +3,7 @@
(type $iii (func (param i32 i32) (result i32))) (type $iii (func (param i32 i32) (result i32)))
(type $iiii (func (param i32 i32 i32) (result i32))) (type $iiii (func (param i32 i32 i32) (result i32)))
(type $iiI (func (param i32 i32) (result i64))) (type $iiI (func (param i32 i32) (result i64)))
(type $iF (func (param i32) (result f64)))
(type $v (func)) (type $v (func))
(global $std/string/str (mut i32) (i32.const 8)) (global $std/string/str (mut i32) (i32.const 8))
(memory $0 1) (memory $0 1)
@ -21,6 +22,9 @@
(data (i32.const 184) "\05\00\00\000\00x\00F\000\00F") (data (i32.const 184) "\05\00\00\000\00x\00F\000\00F")
(data (i32.const 200) "\03\00\00\000\001\001") (data (i32.const 200) "\03\00\00\000\001\001")
(data (i32.const 216) "\04\00\00\000\00x\001\00g") (data (i32.const 216) "\04\00\00\000\00x\001\00g")
(data (i32.const 232) "\03\00\00\000\00.\001")
(data (i32.const 248) "\03\00\00\00.\002\005")
(data (i32.const 264) "\08\00\00\00.\001\00f\00o\00o\00b\00a\00r")
(export "getString" (func $std/string/getString)) (export "getString" (func $std/string/getString))
(export "memory" (memory $0)) (export "memory" (memory $0))
(start $start) (start $start)
@ -607,62 +611,39 @@
) )
) )
) )
(loop $continue|1 (block $break|1
(if (loop $continue|1
(block (result i32) (if
(set_local $3 (block (result i32)
(i32.sub (set_local $3
(tee_local $2
(get_local $3)
)
(i32.const 1)
)
)
(get_local $2)
)
(block
(if
(i32.and
(select
(i32.le_s
(tee_local $2
(i32.load16_u offset=4
(get_local $0)
)
)
(i32.const 57)
)
(i32.ge_s
(get_local $2)
(i32.const 48)
)
(i32.ge_s
(get_local $2)
(i32.const 48)
)
)
(i32.const 1)
)
(set_local $2
(i32.sub (i32.sub
(get_local $2) (tee_local $2
(i32.const 48) (get_local $3)
)
(i32.const 1)
) )
) )
(get_local $2)
)
(block
(if (if
(i32.and (i32.and
(select (select
(i32.le_s (i32.le_s
(get_local $2) (tee_local $2
(i32.const 90) (i32.load16_u offset=4
(get_local $0)
)
)
(i32.const 57)
) )
(i32.ge_s (i32.ge_s
(get_local $2) (get_local $2)
(i32.const 65) (i32.const 48)
) )
(i32.ge_s (i32.ge_s
(get_local $2) (get_local $2)
(i32.const 65) (i32.const 48)
) )
) )
(i32.const 1) (i32.const 1)
@ -670,7 +651,7 @@
(set_local $2 (set_local $2
(i32.sub (i32.sub
(get_local $2) (get_local $2)
(i32.const 55) (i32.const 48)
) )
) )
(if (if
@ -678,15 +659,15 @@
(select (select
(i32.le_s (i32.le_s
(get_local $2) (get_local $2)
(i32.const 122) (i32.const 90)
) )
(i32.ge_s (i32.ge_s
(get_local $2) (get_local $2)
(i32.const 97) (i32.const 65)
) )
(i32.ge_s (i32.ge_s
(get_local $2) (get_local $2)
(i32.const 97) (i32.const 65)
) )
) )
(i32.const 1) (i32.const 1)
@ -694,50 +675,64 @@
(set_local $2 (set_local $2
(i32.sub (i32.sub
(get_local $2) (get_local $2)
(i32.const 87) (i32.const 55)
) )
) )
(return (if
(i64.mul (i32.and
(get_local $5) (select
(get_local $4) (i32.le_s
(get_local $2)
(i32.const 122)
)
(i32.ge_s
(get_local $2)
(i32.const 97)
)
(i32.ge_s
(get_local $2)
(i32.const 97)
)
)
(i32.const 1)
) )
(set_local $2
(i32.sub
(get_local $2)
(i32.const 87)
)
)
(br $break|1)
) )
) )
) )
) (br_if $break|1
(if (i32.ge_s
(i32.ge_s
(get_local $2)
(get_local $1)
)
(return
(i64.mul
(get_local $5)
(get_local $4)
)
)
)
(set_local $4
(i64.add
(i64.mul
(get_local $4)
(i64.extend_s/i32
(get_local $1)
)
)
(i64.extend_s/i32
(get_local $2) (get_local $2)
(get_local $1)
) )
) )
) (set_local $4
(set_local $0 (i64.add
(i32.add (i64.mul
(get_local $0) (get_local $4)
(i32.const 2) (i64.extend_s/i32
(get_local $1)
)
)
(i64.extend_s/i32
(get_local $2)
)
)
) )
(set_local $0
(i32.add
(get_local $0)
(i32.const 2)
)
)
(br $continue|1)
) )
(br $continue|1)
) )
) )
) )
@ -746,7 +741,251 @@
(get_local $4) (get_local $4)
) )
) )
(func $start (; 7 ;) (type $v) (func $std:string/parseFloat (; 7 ;) (type $iF) (param $0 i32) (result f64)
(local $1 i32)
(local $2 i32)
(local $3 f64)
(local $4 f64)
(local $5 f64)
(if
(i32.eqz
(tee_local $2
(i32.load
(get_local $0)
)
)
)
(return
(f64.const nan:0x8000000000000)
)
)
(set_local $5
(if (result f64)
(i32.eq
(tee_local $0
(i32.load16_u offset=4
(tee_local $1
(get_local $0)
)
)
)
(i32.const 45)
)
(block (result f64)
(if
(i32.eqz
(tee_local $2
(i32.sub
(get_local $2)
(i32.const 1)
)
)
)
(return
(f64.const nan:0x8000000000000)
)
)
(drop
(i32.load16_u offset=4
(tee_local $1
(i32.add
(get_local $1)
(i32.const 2)
)
)
)
)
(f64.const -1)
)
(if (result f64)
(i32.eq
(get_local $0)
(i32.const 43)
)
(block (result f64)
(if
(i32.eqz
(tee_local $2
(i32.sub
(get_local $2)
(i32.const 1)
)
)
)
(return
(f64.const nan:0x8000000000000)
)
)
(drop
(i32.load16_u offset=4
(tee_local $1
(i32.add
(get_local $1)
(i32.const 2)
)
)
)
)
(f64.const 1)
)
(f64.const 1)
)
)
)
(block $break|0
(loop $continue|0
(if
(block (result i32)
(set_local $2
(i32.sub
(tee_local $0
(get_local $2)
)
(i32.const 1)
)
)
(get_local $0)
)
(block
(if
(i32.eq
(tee_local $0
(i32.load16_u offset=4
(get_local $1)
)
)
(i32.const 46)
)
(block
(set_local $1
(i32.add
(get_local $1)
(i32.const 2)
)
)
(set_local $4
(f64.const 0.1)
)
(block $break|1
(loop $continue|1
(if
(block (result i32)
(set_local $2
(i32.sub
(tee_local $0
(get_local $2)
)
(i32.const 1)
)
)
(get_local $0)
)
(block
(if
(i32.and
(select
(i32.eq
(tee_local $0
(i32.load16_u offset=4
(get_local $1)
)
)
(i32.const 69)
)
(i32.eq
(get_local $0)
(i32.const 101)
)
(i32.eq
(get_local $0)
(i32.const 69)
)
)
(i32.const 1)
)
(unreachable)
)
(br_if $break|1
(i32.gt_u
(tee_local $0
(i32.sub
(get_local $0)
(i32.const 48)
)
)
(i32.const 9)
)
)
(set_local $3
(f64.add
(get_local $3)
(f64.mul
(f64.convert_s/i32
(get_local $0)
)
(get_local $4)
)
)
)
(set_local $4
(f64.mul
(get_local $4)
(f64.const 0.1)
)
)
(set_local $1
(i32.add
(get_local $1)
(i32.const 2)
)
)
(br $continue|1)
)
)
)
)
(br $break|0)
)
)
(br_if $break|0
(i32.ge_u
(tee_local $0
(i32.sub
(get_local $0)
(i32.const 48)
)
)
(i32.const 10)
)
)
(set_local $3
(f64.add
(f64.mul
(get_local $3)
(f64.const 10)
)
(f64.convert_s/i32
(get_local $0)
)
)
)
(set_local $1
(i32.add
(get_local $1)
(i32.const 2)
)
)
(br $continue|0)
)
)
)
)
(f64.mul
(get_local $5)
(get_local $3)
)
)
(func $start (; 8 ;) (type $v)
(if (if
(i32.ne (i32.ne
(get_global $std/string/str) (get_global $std/string/str)
@ -908,5 +1147,50 @@
) )
(unreachable) (unreachable)
) )
(if
(f64.ne
(call $std:string/parseFloat
(i32.const 120)
)
(f64.const 0)
)
(unreachable)
)
(if
(f64.ne
(call $std:string/parseFloat
(i32.const 128)
)
(f64.const 1)
)
(unreachable)
)
(if
(f64.ne
(call $std:string/parseFloat
(i32.const 232)
)
(f64.const 0.1)
)
(unreachable)
)
(if
(f64.ne
(call $std:string/parseFloat
(i32.const 248)
)
(f64.const 0.25)
)
(unreachable)
)
(if
(f64.ne
(call $std:string/parseFloat
(i32.const 264)
)
(f64.const 0.1)
)
(unreachable)
)
) )
) )

View File

@ -3,7 +3,7 @@
var str: string = "hi, I'm a string"; var str: string = "hi, I'm a string";
// exactly once in static memory // exactly once in static memory
assert(changetype<usize>(str) === changetype<usize>("hi, I'm a string")); assert(changetype<usize>(str) == changetype<usize>("hi, I'm a string"));
assert(str.length == 16); assert(str.length == 16);
assert(str.charCodeAt(0) == 0x68); assert(str.charCodeAt(0) == 0x68);
@ -25,3 +25,9 @@ assert(parseInt("0xf0f") == 0xf0f);
assert(parseInt("0xF0F") == 0xf0f); assert(parseInt("0xF0F") == 0xf0f);
assert(parseInt("011") == 11); // not octal assert(parseInt("011") == 11); // not octal
assert(parseInt("0x1g") == 1); // not valid assert(parseInt("0x1g") == 1); // not valid
assert(parseFloat("0") == 0);
assert(parseFloat("1") == 1);
assert(parseFloat("0.1") == 0.1);
assert(parseFloat(".25") == 0.25);
assert(parseFloat(".1foobar") == 0.1);

View File

@ -3,11 +3,13 @@
(type $iii (func (param i32 i32) (result i32))) (type $iii (func (param i32 i32) (result i32)))
(type $iiii (func (param i32 i32 i32) (result i32))) (type $iiii (func (param i32 i32 i32) (result i32)))
(type $iiI (func (param i32 i32) (result i64))) (type $iiI (func (param i32 i32) (result i64)))
(type $iF (func (param i32) (result f64)))
(type $v (func)) (type $v (func))
(global $std/string/str (mut i32) (i32.const 8)) (global $std/string/str (mut i32) (i32.const 8))
(global $std:string/HEAD i32 (i32.const 4)) (global $std:string/HEAD i32 (i32.const 4))
(global $std:string/CharCode.PLUS i32 (i32.const 43)) (global $std:string/CharCode.PLUS i32 (i32.const 43))
(global $std:string/CharCode.MINUS i32 (i32.const 45)) (global $std:string/CharCode.MINUS i32 (i32.const 45))
(global $std:string/CharCode.DOT i32 (i32.const 46))
(global $std:string/CharCode._0 i32 (i32.const 48)) (global $std:string/CharCode._0 i32 (i32.const 48))
(global $std:string/CharCode._1 i32 (i32.const 49)) (global $std:string/CharCode._1 i32 (i32.const 49))
(global $std:string/CharCode._2 i32 (i32.const 50)) (global $std:string/CharCode._2 i32 (i32.const 50))
@ -20,15 +22,17 @@
(global $std:string/CharCode._9 i32 (i32.const 57)) (global $std:string/CharCode._9 i32 (i32.const 57))
(global $std:string/CharCode.A i32 (i32.const 65)) (global $std:string/CharCode.A i32 (i32.const 65))
(global $std:string/CharCode.B i32 (i32.const 66)) (global $std:string/CharCode.B i32 (i32.const 66))
(global $std:string/CharCode.E i32 (i32.const 69))
(global $std:string/CharCode.O i32 (i32.const 79)) (global $std:string/CharCode.O i32 (i32.const 79))
(global $std:string/CharCode.X i32 (i32.const 88)) (global $std:string/CharCode.X i32 (i32.const 88))
(global $std:string/CharCode.Z i32 (i32.const 90)) (global $std:string/CharCode.Z i32 (i32.const 90))
(global $std:string/CharCode.a i32 (i32.const 97)) (global $std:string/CharCode.a i32 (i32.const 97))
(global $std:string/CharCode.b i32 (i32.const 98)) (global $std:string/CharCode.b i32 (i32.const 98))
(global $std:string/CharCode.e i32 (i32.const 101))
(global $std:string/CharCode.o i32 (i32.const 111)) (global $std:string/CharCode.o i32 (i32.const 111))
(global $std:string/CharCode.x i32 (i32.const 120)) (global $std:string/CharCode.x i32 (i32.const 120))
(global $std:string/CharCode.z i32 (i32.const 122)) (global $std:string/CharCode.z i32 (i32.const 122))
(global $HEAP_BASE i32 (i32.const 228)) (global $HEAP_BASE i32 (i32.const 284))
(memory $0 1) (memory $0 1)
(data (i32.const 8) "\10\00\00\00h\00i\00,\00 \00I\00\'\00m\00 \00a\00 \00s\00t\00r\00i\00n\00g\00") (data (i32.const 8) "\10\00\00\00h\00i\00,\00 \00I\00\'\00m\00 \00a\00 \00s\00t\00r\00i\00n\00g\00")
(data (i32.const 48) "\02\00\00\00h\00i\00") (data (i32.const 48) "\02\00\00\00h\00i\00")
@ -45,6 +49,9 @@
(data (i32.const 184) "\05\00\00\000\00x\00F\000\00F\00") (data (i32.const 184) "\05\00\00\000\00x\00F\000\00F\00")
(data (i32.const 200) "\03\00\00\000\001\001\00") (data (i32.const 200) "\03\00\00\000\001\001\00")
(data (i32.const 216) "\04\00\00\000\00x\001\00g\00") (data (i32.const 216) "\04\00\00\000\00x\001\00g\00")
(data (i32.const 232) "\03\00\00\000\00.\001\00")
(data (i32.const 248) "\03\00\00\00.\002\005\00")
(data (i32.const 264) "\08\00\00\00.\001\00f\00o\00o\00b\00a\00r\00")
(export "getString" (func $std/string/getString)) (export "getString" (func $std/string/getString))
(export "memory" (memory $0)) (export "memory" (memory $0))
(start $start) (start $start)
@ -874,12 +881,7 @@
) )
) )
) )
(return (br $break|1)
(i64.mul
(get_local $5)
(get_local $7)
)
)
) )
) )
) )
@ -888,12 +890,7 @@
(get_local $4) (get_local $4)
(get_local $1) (get_local $1)
) )
(return (br $break|1)
(i64.mul
(get_local $5)
(get_local $7)
)
)
) )
(set_local $7 (set_local $7
(i64.add (i64.add
@ -927,7 +924,288 @@
) )
) )
) )
(func $start (; 8 ;) (type $v) (func $std:string/parseFloat (; 8 ;) (type $iF) (param $0 i32) (result f64)
(local $1 i32)
(local $2 i32)
(local $3 i32)
(local $4 f64)
(local $5 f64)
(local $6 i32)
(local $7 f64)
(set_local $1
(i32.load
(get_local $0)
)
)
(if
(i32.eqz
(get_local $1)
)
(return
(f64.const nan:0x8000000000000)
)
)
(set_local $2
(get_local $0)
)
(set_local $3
(i32.load16_u offset=4
(get_local $2)
)
)
(nop)
(if
(i32.eq
(get_local $3)
(i32.const 45)
)
(block
(if
(i32.eqz
(tee_local $1
(i32.sub
(get_local $1)
(i32.const 1)
)
)
)
(return
(f64.const nan:0x8000000000000)
)
)
(set_local $3
(i32.load16_u offset=4
(tee_local $2
(i32.add
(get_local $2)
(i32.const 2)
)
)
)
)
(set_local $4
(f64.neg
(f64.const 1)
)
)
)
(if
(i32.eq
(get_local $3)
(i32.const 43)
)
(block
(if
(i32.eqz
(tee_local $1
(i32.sub
(get_local $1)
(i32.const 1)
)
)
)
(return
(f64.const nan:0x8000000000000)
)
)
(set_local $3
(i32.load16_u offset=4
(tee_local $2
(i32.add
(get_local $2)
(i32.const 2)
)
)
)
)
(set_local $4
(f64.const 1)
)
)
(set_local $4
(f64.const 1)
)
)
)
(set_local $5
(f64.const 0)
)
(block $break|0
(loop $continue|0
(if
(block (result i32)
(set_local $6
(get_local $1)
)
(set_local $1
(i32.sub
(get_local $6)
(i32.const 1)
)
)
(get_local $6)
)
(block
(block
(set_local $3
(i32.load16_u offset=4
(get_local $2)
)
)
(if
(i32.eq
(get_local $3)
(i32.const 46)
)
(block
(set_local $2
(i32.add
(get_local $2)
(i32.const 2)
)
)
(set_local $7
(f64.const 0.1)
)
(block $break|1
(loop $continue|1
(if
(block (result i32)
(set_local $6
(get_local $1)
)
(set_local $1
(i32.sub
(get_local $6)
(i32.const 1)
)
)
(get_local $6)
)
(block
(block
(set_local $3
(i32.load16_u offset=4
(get_local $2)
)
)
(if
(i32.and
(if (result i32)
(i32.ne
(i32.eq
(get_local $3)
(i32.const 69)
)
(i32.const 0)
)
(i32.eq
(get_local $3)
(i32.const 69)
)
(i32.eq
(get_local $3)
(i32.const 101)
)
)
(i32.const 1)
)
(if
(i32.eqz
(i32.const 0)
)
(unreachable)
)
)
(set_local $3
(i32.sub
(get_local $3)
(i32.const 48)
)
)
(if
(i32.gt_u
(get_local $3)
(i32.const 9)
)
(br $break|1)
)
(set_local $5
(f64.add
(get_local $5)
(f64.mul
(f64.convert_s/i32
(get_local $3)
)
(get_local $7)
)
)
)
(set_local $7
(f64.mul
(get_local $7)
(f64.const 0.1)
)
)
(set_local $2
(i32.add
(get_local $2)
(i32.const 2)
)
)
)
(br $continue|1)
)
)
)
)
(br $break|0)
)
)
(set_local $3
(i32.sub
(get_local $3)
(i32.const 48)
)
)
(if
(i32.ge_u
(get_local $3)
(i32.const 10)
)
(br $break|0)
)
(set_local $5
(f64.add
(f64.mul
(get_local $5)
(f64.const 10)
)
(f64.convert_s/i32
(get_local $3)
)
)
)
(set_local $2
(i32.add
(get_local $2)
(i32.const 2)
)
)
)
(br $continue|0)
)
)
)
)
(return
(f64.mul
(get_local $4)
(get_local $5)
)
)
)
(func $start (; 9 ;) (type $v)
(if (if
(i32.eqz (i32.eqz
(i32.eq (i32.eq
@ -1115,6 +1393,61 @@
) )
(unreachable) (unreachable)
) )
(if
(i32.eqz
(f64.eq
(call $std:string/parseFloat
(i32.const 120)
)
(f64.const 0)
)
)
(unreachable)
)
(if
(i32.eqz
(f64.eq
(call $std:string/parseFloat
(i32.const 128)
)
(f64.const 1)
)
)
(unreachable)
)
(if
(i32.eqz
(f64.eq
(call $std:string/parseFloat
(i32.const 232)
)
(f64.const 0.1)
)
)
(unreachable)
)
(if
(i32.eqz
(f64.eq
(call $std:string/parseFloat
(i32.const 248)
)
(f64.const 0.25)
)
)
(unreachable)
)
(if
(i32.eqz
(f64.eq
(call $std:string/parseFloat
(i32.const 264)
)
(f64.const 0.1)
)
)
(unreachable)
)
) )
) )
(; (;