Skip to content

Commit ad11123

Browse files
committed
add ** operator and stringifies bigint as string in JSON
1 parent ebce991 commit ad11123

File tree

12 files changed

+62
-17
lines changed

12 files changed

+62
-17
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ This is a list of features in ECMA-262 that are planned or implemented ("[x]" do
131131
* [ ] index access (`[0]` and `.["foo"]`)
132132
* [ ] property access (`.foo`)
133133
* [ ] `typeof` operator
134-
* [ ] [WIP] arithmetic operators (`+`, `-`, `*`, `/`, `%`, `**`)
134+
* [x] arithmetic operators (`+`, `-`, `*`, `/`, `%`, `**`)
135135
* [x] bitwise operators (`~`, `&`, `|`, `^`, `<<`, `>>`, `>>>`)
136136
* [ ] assignment operators (`=`, `+=`, `-=`, `*=`, `/=`, `%=`, `**=`, `<<=`, `>>=`, `>>>=`, `&=`, `|=`, `^=`)
137137
* [x] comparison operators (`==`, `!=`, `===`, `!==`, `<`, `>`, `<=`, `>=`)

spec/pow.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export const a = 1 ** 1;
2+
export const b = 2 ** 32;
3+
export const c = 2n ** 32n;
4+
export const d = 2n ** 50n;

spec/pow.ts.stdout

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"a": 1,
3+
"b": 4294967296,
4+
"c": "4294967296",
5+
"d": "1125899906842624"
6+
}

src/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ pub enum ExprEnum<'src> {
6060
Mul(Box<Expression<'src>>, Box<Expression<'src>>),
6161
Div(Box<Expression<'src>>, Box<Expression<'src>>),
6262
Mod(Box<Expression<'src>>, Box<Expression<'src>>),
63+
Pow(Box<Expression<'src>>, Box<Expression<'src>>),
6364
BwOr(Box<Expression<'src>>, Box<Expression<'src>>),
6465
BwAnd(Box<Expression<'src>>, Box<Expression<'src>>),
6566
BwXor(Box<Expression<'src>>, Box<Expression<'src>>),

src/compiler.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ impl Compiler {
221221
ExprEnum::Mul(lhs, rhs) => self.bin_op(OpCode::Mul, lhs, rhs)?,
222222
ExprEnum::Div(lhs, rhs) => self.bin_op(OpCode::Div, lhs, rhs)?,
223223
ExprEnum::Mod(lhs, rhs) => self.bin_op(OpCode::Mod, lhs, rhs)?,
224+
ExprEnum::Pow(lhs, rhs) => self.bin_op(OpCode::Pow, lhs, rhs)?,
224225
ExprEnum::BwOr(lhs, rhs) => self.bin_op(OpCode::BwOr, lhs, rhs)?,
225226
ExprEnum::BwAnd(lhs, rhs) => self.bin_op(OpCode::BwAnd, lhs, rhs)?,
226227
ExprEnum::BwXor(lhs, rhs) => self.bin_op(OpCode::BwXor, lhs, rhs)?,

src/instructions.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ pub enum OpCode {
1515
Add,
1616
Sub,
1717
Mul,
18-
Mod,
1918
Div,
19+
Mod,
20+
Pow,
2021
BwOr,
2122
BwAnd,
2223
BwXor,

src/main.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -301,12 +301,12 @@ mod tests {
301301
result,
302302
json!(
303303
{
304-
"zero": 0,
305-
"answer": 42,
306-
"minus": -42,
307-
"w_underscore": 1000000,
308-
"i32_max": 2147483647i32,
309-
"i64_max": 9223372036854775807i64
304+
"zero": "0",
305+
"answer": "42",
306+
"minus": "-42",
307+
"w_underscore": "1000000",
308+
"i32_max": "2147483647",
309+
"i64_max": "9223372036854775807"
310310
}
311311
)
312312
);
@@ -320,7 +320,7 @@ mod tests {
320320
"#,
321321
)
322322
.unwrap();
323-
assert_eq!(result, json!({ "a": 43 }));
323+
assert_eq!(result, json!({ "a": "43" }));
324324
}
325325

326326
#[test]
@@ -331,7 +331,7 @@ mod tests {
331331
"#,
332332
)
333333
.unwrap();
334-
assert_eq!(result, json!({ "a": 41 }));
334+
assert_eq!(result, json!({ "a": "41" }));
335335
}
336336

337337
#[test]
@@ -342,7 +342,7 @@ mod tests {
342342
"#,
343343
)
344344
.unwrap();
345-
assert_eq!(result, json!({ "a": 84 }));
345+
assert_eq!(result, json!({ "a": "84" }));
346346
}
347347

348348
#[test]
@@ -353,7 +353,7 @@ mod tests {
353353
"#,
354354
)
355355
.unwrap();
356-
assert_eq!(result, json!({ "a": 14 }));
356+
assert_eq!(result, json!({ "a": "14" }));
357357
}
358358

359359
// TODO: literal types are not yet supported so the error message does not match TypeScript compiler's.

src/parser.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ fn unary_op(i: Span) -> IResult<Span, Expression> {
118118
}
119119
}
120120

121-
fn factor(i: Span) -> IResult<Span, Expression> {
122-
alt((
121+
fn factor(input: Span) -> IResult<Span, Expression> {
122+
let (i, expr) = alt((
123123
undefined_literal,
124124
null_literal,
125125
true_literal,
@@ -134,7 +134,21 @@ fn factor(i: Span) -> IResult<Span, Expression> {
134134
func_call,
135135
ident,
136136
parens,
137-
))(i)
137+
))(input)?;
138+
139+
let Ok((i, _)) = tag::<&str, Span, Error>("**")(i) else {
140+
return Ok((i, expr));
141+
};
142+
143+
let (i, rhs) = space_delimited(factor)(i)?;
144+
Ok((
145+
i,
146+
Expression {
147+
expr: ExprEnum::Pow(Box::new(expr), Box::new(rhs)),
148+
span: input,
149+
},
150+
))
151+
138152
}
139153

140154
fn func_call(i: Span) -> IResult<Span, Expression> {

src/ser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ impl Serialize for Value {
2020
serializer.serialize_f64(*value)
2121
}
2222
}
23-
Self::Int(value) => serializer.serialize_i64(*value),
23+
Self::Int(value) => serializer.serialize_str(value.to_string().as_str()),
2424
Self::Str(value) => serializer.serialize_str(value),
2525
Self::Array(value) => value.serialize(serializer),
2626
Self::Object(value) => {

src/type_checker.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ fn tc_expr<'src>(
275275
Mul(lhs, rhs) => tc_bin_arithmetic_op(lhs, rhs, ctx, "*")?,
276276
Div(lhs, rhs) => tc_bin_arithmetic_op(lhs, rhs, ctx, "/")?,
277277
Mod(lhs, rhs) => tc_bin_arithmetic_op(lhs, rhs, ctx, "%")?,
278+
Pow(lhs, rhs) => tc_bin_arithmetic_op(lhs, rhs, ctx, "**")?,
278279
BwAnd(lhs, rhs) => tc_bin_arithmetic_op(lhs, rhs, ctx, "&")?,
279280
BwOr(lhs, rhs) => tc_bin_arithmetic_op(lhs, rhs, ctx, "|")?,
280281
BwXor(lhs, rhs) => tc_bin_arithmetic_op(lhs, rhs, ctx, "^")?,

0 commit comments

Comments
 (0)