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

assigning binary, octal, hex value to number #75

Merged
merged 1 commit into from
Nov 27, 2023
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
13 changes: 3 additions & 10 deletions src/backend/binaryen/wasm_expr_gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ export class WASMExpressionGen {
} else {
return FunctionalFuncs.generateStringForStructArrayStr(
this.module,
processEscape(value.value as string),
value.value as string,
);
}
}
Expand Down Expand Up @@ -330,15 +330,8 @@ export class WASMExpressionGen {
}

private createStringRef(value: string): binaryen.ExpressionRef {
let str = value;
if (
(str.startsWith("'") && str.endsWith("'")) ||
(str.startsWith('"') && str.endsWith('"'))
) {
str = str.substring(1, str.length - 1);
}
const ptr = this.wasmCompiler.generateRawString(str);
const len = UtilFuncs.utf16ToUtf8(str).length;
const ptr = this.wasmCompiler.generateRawString(value);
const len = UtilFuncs.utf16ToUtf8(value).length;
return FunctionalFuncs.generateStringForStringref(
this.module,
this.module.i32.const(ptr),
Expand Down
14 changes: 11 additions & 3 deletions src/expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import ts from 'typescript';
import { ParserContext } from './frontend.js';
import { ClosureEnvironment, FunctionScope } from './scope.js';
import { Variable } from './variable.js';
import { getCurScope, addSourceMapLoc, isTypeGeneric } from './utils.js';
import {
getCurScope,
addSourceMapLoc,
isTypeGeneric,
processEscape,
decimalization,
} from './utils.js';
import {
TSArray,
TSFunction,
Expand Down Expand Up @@ -495,14 +501,16 @@ export default class ExpressionProcessor {
}
case ts.SyntaxKind.NumericLiteral: {
res = new NumberLiteralExpression(
parseFloat((<ts.NumericLiteral>node).getText()),
parseFloat(
decimalization((<ts.NumericLiteral>node).getText()),
),
);
res.setExprType(this.typeResolver.generateNodeType(node));
break;
}
case ts.SyntaxKind.StringLiteral: {
res = new StringLiteralExpression(
(<ts.StringLiteral>node).getText(),
processEscape((<ts.StringLiteral>node).getText()),
);
res.setExprType(this.typeResolver.generateNodeType(node));
break;
Expand Down
64 changes: 59 additions & 5 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,21 +401,30 @@ export function addSourceMapLoc(irNode: Statement | Expression, node: ts.Node) {
irNode.debugLoc = { line: line, character: character };
}

// The character '\' in the string got from API getText is not treated
// as a escape character.
/**
* @describe process escapes in a string
* @param str the raw string got from API getText
* @returns a new str
*/
export function processEscape(str: string) {
const escapes1 = ['"', "'", '\\'];
const escapes2 = ['n', 'r', 't', 'b', 'f'];
const appendingStr = ['\n', '\r', '\t', '\b', '\f'];
let newStr = '';
let code: string;
for (let i = 0; i < str.length; i++) {
if (
str[i] == '\\' &&
i < str.length - 1 &&
(escapes1.includes(str[i + 1]) || escapes2.includes(str[i + 1]))
) {
if (str[i] == '\\' && i < str.length - 1) {
if (escapes1.includes(str[i + 1])) {
// binaryen will generate escape automaticlly for characters in escapes1
newStr += str[i + 1];
} else if (escapes2.includes(str[i + 1])) {
newStr += appendingStr[escapes2.indexOf(str[i + 1])];
} else if (str[i + 1] == 'x') {
code = decimalizationInternal(str.substring(i + 2, i + 4), 16);
newStr += String.fromCharCode(parseFloat(code));
i += 2;
}
i += 1;
continue;
Expand All @@ -428,6 +437,51 @@ export function processEscape(str: string) {
return newStr;
}

export function decimalization(value: string) {
let systemNumeration = 0;
if (value.length < 2) {
return value;
}
if (value[0] == '0') {
switch (value[1]) {
case 'b':
case 'B': {
systemNumeration = 2;
break;
}
case 'o':
case 'O': {
systemNumeration = 8;
break;
}
case 'x':
case 'X': {
systemNumeration = 16;
break;
}
}
}
if (systemNumeration == 0) {
return value;
}
return decimalizationInternal(
value.substring(2, value.length),
systemNumeration,
);
}

function decimalizationInternal(value: string, systemNumeration: number) {
let decimal = 0;
let num = 0;
let code = 0;
for (let i = 0; i < value.length; i++) {
code = value[i].charCodeAt(0);
num = code >= 65 && code <= 70 ? 10 + code - 65 : parseFloat(value[i]);
decimal = decimal * systemNumeration + num;
}
return decimal.toString();
}

/**
* @describe create a new classScope based on classType information
* @param originalClassScope the original ClassScope to be specialized
Expand Down
28 changes: 28 additions & 0 deletions tests/samples/decimalization.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2023 Xiaomi Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/

export function initNumberWithBinary() {
let value = 0b00101; // 5
console.log(value);

value = 0B001010; // 10
console.log(value);
}

export function initNumberWithOctal() {
let value = 0O000171; // 64 + 56 + 1 = 121
console.log(value);

value = 0o0001710; // 968
console.log(value);
}

export function initNumberWithHex() {
let value = 0x00AF1; // 10 * 16^2 + 15 * 16 + 1 = 2801
console.log(value);

value = 0X00AF0; // 2800
console.log(value);
}
5 changes: 5 additions & 0 deletions tests/samples/string_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,9 @@ export function templateString() {
console.log(`${obj.du} is undefined`);
}

export function stringContainHex() {
let s: string = "\x41B\x43";
console.log(s);
}


27 changes: 26 additions & 1 deletion tools/validate/wamr/validation.json
Original file line number Diff line number Diff line change
Expand Up @@ -3446,6 +3446,11 @@
"name": "templateString",
"args": [],
"result": "1 world\n11 world\nHello world Hello world\nhello is not 10\nhi x\n1 and Hello is x\n10\nhi\nhi is x\n10 is 10\n0 is 0\n10 is 10\n1,2\n2\n1 is 1\n[object Object] is object\nhi is hi\n0 is 0\nundefined is undefined"
},
{
"name": "stringContainHex",
"args": [],
"result": "ABC"
}
]
},
Expand Down Expand Up @@ -3595,7 +3600,7 @@
{
"name": "JSONTest3",
"args": [],
"result": "42\n{\"result\":true,\"count\":42}\n{\"''''\\n\\r\\t\\\\1\":\"2\\\\n\"}"
"result": "42\n{\"result\":true,\"count\":42}\n{\"''''\\n\\r\\t\\\\1\":\"2\\n\"}"
}
]
},
Expand Down Expand Up @@ -4167,5 +4172,25 @@
"result": "a\nb"
}
]
},
{
"module": "decimalization",
"entries": [
{
"name": "initNumberWithBinary",
"args": [],
"result": "5\n10"
},
{
"name": "initNumberWithOctal",
"args": [],
"result": "121\n968"
},
{
"name": "initNumberWithHex",
"args": [],
"result": "2801\n2800"
}
]
}
]