Skip to content

Commit

Permalink
Changes
Browse files Browse the repository at this point in the history
add file with implementation of const, remove const parts from let.ts
extract const and assign from let.ts, extract tests for const and assign
from let tests
  • Loading branch information
dastin-sandura committed Oct 28, 2020
1 parent 58a8383 commit 7dd2b2b
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 24 deletions.
27 changes: 27 additions & 0 deletions src/askvm/resources/core/__test__/assign.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { runUntyped } from '../../..';
import { parse } from '../../../../askcode';
import * as core from '../../core';
import { assignRes } from '../assign';

const values = {};

function ask(code: string) {
return runUntyped(
{
resources: { ...core, assignRes },
values,
},
parse(code)
);
}

describe(`assign`, function () {
it(`should assign value with the assign resource`, async function () {
const initialValue = 6;
const assignedValue = 4;
const resolvedValue = await ask(
`ask(let('a',${initialValue}),assign('a',${assignedValue}))`
);
expect(resolvedValue).toEqual(assignedValue);
});
});
43 changes: 43 additions & 0 deletions src/askvm/resources/core/__test__/const.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { runUntyped } from '../../..';
import { parse } from '../../../../askcode';
import * as core from '../../core';
import { constRes } from '../const';

const values = {};

function ask(code: string) {
return runUntyped(
{
resources: { ...core, constRes },
values,
},
parse(code)
);
}

describe(`const`, function () {
it(`should assign value to a const variable on initialization`, async function () {
const value = 6;
await expect(
ask(`ask(const('a',${value}),call(get('get'), 'a'))`)
).resolves.toEqual(value);
});

it(`should throw when trying to assign to const`, async function () {
const value = 6;
await expect(
ask(`ask(const('a',${value}),call(get('get'),assign('a',4),'a'))`)
).rejects.toThrow(`Cannot assign to a constant variable "a"`);
});

const reservedWords = ['resources'];

it(`should not allow reserved words as constant name`, async function () {
for (let i = 0; i < reservedWords.length; i++) {
const reservedWord = reservedWords[i];
await expect(ask(`ask(const('resources',6))`)).rejects.toThrow(
`Key "${reservedWord}" cannot be redeclared`
);
}
});
});
22 changes: 2 additions & 20 deletions src/askvm/resources/core/__test__/let.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,9 @@ function ask(code: string) {
}

describe(`let`, function () {
it(`should throw when trying to assign to const`, async function () {
it(`should assign value to a let variable on initialization`, async function () {
const value = 6;
await expect(
ask(`ask(const('a',${value}),call(get('get'),assign('a',4),'a'))`)
).rejects.toThrow(`Cannot assign to a constant variable "a"`);
});

it(`should assign value on initialization`, async function () {
const value = 6;
await expect(
ask(`ask(let('a',${value}),call(get('get'), 'a'))`)
).resolves.toEqual(value);
});

it(`should assign value with the assign resource`, async function () {
const initialValue = 6;
const assignedValue = 4;
const resolvedValue = await ask(
`ask(let('a',${initialValue}),assign('a',${assignedValue}))`
);
expect(resolvedValue).toEqual(assignedValue);
await expect(ask(`ask(let('a',${value}))`)).resolves.toEqual(value);
});

const reservedWords = ['resources'];
Expand Down
52 changes: 52 additions & 0 deletions src/askvm/resources/core/assign.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {
any,
resource,
run,
runUntyped,
Options,
TypedValue,
JSONable,
} from '../../lib';

function assignValue(
valueObject: { [key: string]: any },
key: string,
assignedValue: any
) {
if (Object.isFrozen(valueObject[key]))
throw new Error(`Cannot assign to a constant variable "${key}"`);
valueObject[key] = assignedValue;
}

export const assignRes = resource({
type: any,
async compute(options, code, args): Promise<TypedValue<JSONable>> {
const { params: children = [] } = code;

const key: any = await runUntyped(options, children[0]); // FIXME any
const value = await run(options, children[1]);

if (key === 'resources') {
throw new Error(`Key "resources" cannot be redeclared`);
}

if (code.name === 'assign') {
for (
let prototype: Options | undefined = options;
prototype;
prototype = prototype?.prototype
) {
const { values = {} } = prototype;
if (Object.prototype.hasOwnProperty.call(values, key)) {
assignValue(values, key, value);
return value;
}
}
throw new Error(`Cannot assign to an unknown variable "${key}"`);
}

options.values![key] = value;

return value;
},
});
42 changes: 42 additions & 0 deletions src/askvm/resources/core/const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
any,
resource,
run,
runUntyped,
Options,
TypedValue,
JSONable,
} from '../../lib';

function assignValue(
valueObject: { [key: string]: any },
key: string,
assignedValue: any
) {
if (Object.isFrozen(valueObject[key]))
throw new Error(`Cannot assign to a constant variable "${key}"`);
valueObject[key] = assignedValue;
}

export const constRes = resource({
type: any,
async compute(options, code, args): Promise<TypedValue<JSONable>> {
console.log(options);
console.log(code);
const { params: children = [] } = code;

const key: any = await runUntyped(options, children[0]); // FIXME any
const value = await run(options, children[1]);

if (key === 'resources') {
throw new Error(`Key "resources" cannot be redeclared`);
}

options.values![key] = value;

if (code.name === 'const') {
Object.freeze(options.values![key]);
}
return value;
},
});
4 changes: 3 additions & 1 deletion src/askvm/resources/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export * from './fun';
export * from './get';
export { ifRes as if } from './if';
export * from './is';
export { letRes as let, letRes as const, letRes as assign } from './let';
export { letRes as let } from './let';
export { constRes as const } from './const';
export { assignRes as assign } from './assign';
export * from './list';
export * from './logicalOr';
export * from './not';
Expand Down
3 changes: 0 additions & 3 deletions src/askvm/resources/core/let.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ export const letRes = resource({

options.values![key] = value;

if (code.name === 'const') {
Object.freeze(options.values![key]);
}
return value;
},
});

0 comments on commit 7dd2b2b

Please sign in to comment.