Skip to content

Commit

Permalink
feat: support unary expressions (#106)
Browse files Browse the repository at this point in the history
  • Loading branch information
prevwong authored Nov 6, 2023
1 parent 0792582 commit 377b50e
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .changeset/sixty-pumpkins-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@rekajs/parser': patch
'@rekajs/types': patch
'@rekajs/core': patch
---

Support unary expressions
10 changes: 10 additions & 0 deletions packages/core/src/expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,16 @@ export const computeExpression = (
return fn(...args);
}

if (expr instanceof t.UnaryExpression) {
const value = computeExpression(expr.argument, reka, env);

if (expr.operator === '-') {
return -value;
}

throw new Error(`Unknown unary operator: ${expr.operator}`);
}

if (expr instanceof t.IfStatement) {
const bool = computeExpression(expr.condition, reka, env, ctx);

Expand Down
9 changes: 9 additions & 0 deletions packages/parser/src/tests/parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,13 @@ describe('Parser', () => {
],
});
});
it('should be able to parse negative values', () => {
expect(Parser.parseExpression('-1')).toMatchObject({
operator: '-',
argument: {
type: 'Literal',
value: 1,
},
});
});
});
3 changes: 3 additions & 0 deletions packages/types/src/generated/builder.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export const func = (...args: ConstructorParameters<typeof t.Func>) =>
export const callExpression = (
...args: ConstructorParameters<typeof t.CallExpression>
) => new t.CallExpression(...args);
export const unaryExpression = (
...args: ConstructorParameters<typeof t.UnaryExpression>
) => new t.UnaryExpression(...args);
export const conditionalExpression = (
...args: ConstructorParameters<typeof t.ConditionalExpression>
) => new t.ConditionalExpression(...args);
Expand Down
18 changes: 18 additions & 0 deletions packages/types/src/generated/types.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,22 @@ export class CallExpression extends Expression {

Schema.register('CallExpression', CallExpression);

type UnaryExpressionParameters = {
meta?: Record<string, any>;
operator: '-' | '+';
argument: Expression;
};

export class UnaryExpression extends Expression {
declare operator: '-' | '+';
declare argument: Expression;
constructor(value: UnaryExpressionParameters) {
super('UnaryExpression', value);
}
}

Schema.register('UnaryExpression', UnaryExpression);

type ConditionalExpressionParameters = {
meta?: Record<string, any>;
condition: Expression;
Expand Down Expand Up @@ -815,6 +831,7 @@ export type Any =
| Block
| Func
| CallExpression
| UnaryExpression
| ConditionalExpression
| IfStatement
| Assignment
Expand Down Expand Up @@ -864,6 +881,7 @@ export type Visitor = {
Block: (node: Block) => any;
Func: (node: Func) => any;
CallExpression: (node: CallExpression) => any;
UnaryExpression: (node: UnaryExpression) => any;
ConditionalExpression: (node: ConditionalExpression) => any;
IfStatement: (node: IfStatement) => any;
Assignment: (node: Assignment) => any;
Expand Down
8 changes: 8 additions & 0 deletions packages/types/src/types.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ Schema.define('CallExpression', {
}),
});

Schema.define('UnaryExpression', {
extends: 'Expression',
fields: (t) => ({
operator: t.union(t.enumeration('-', '+')),
argument: t.node('Expression'),
}),
});

Schema.define('ConditionalExpression', {
extends: 'Expression',
fields: (t) => ({
Expand Down

1 comment on commit 377b50e

@vercel
Copy link

@vercel vercel bot commented on 377b50e Nov 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

reka – ./

rekajs.vercel.app
reka-git-main-prevwong.vercel.app
reka-prevwong.vercel.app
reka.js.org

Please sign in to comment.