Skip to content

Commit

Permalink
Can now integrated core functions into the language
Browse files Browse the repository at this point in the history
  • Loading branch information
dallonf committed Oct 7, 2020
1 parent d5161b7 commit 8ac0a5d
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 12 deletions.
11 changes: 8 additions & 3 deletions packages/proto-compiler/src/analyzer.ts
@@ -1,10 +1,10 @@
import * as ast from './ast';
import coreLibrary from './coreLibrary';

export type ValueType =
| KeywordValueType
| DeclarationValueType
| InstanceValueType;
| InstanceValueType
| CoreFunctionValueType;

export type DeclarationValueType =
| EffectDeclarationValueType
Expand Down Expand Up @@ -37,6 +37,11 @@ export interface TypeDeclarationValueType {
symbol: symbol;
}

export interface CoreFunctionValueType {
kind: 'coreFn';
name: string;
}

interface InstanceValueType {
kind: 'instance';
name?: string;
Expand Down Expand Up @@ -127,7 +132,7 @@ const analyzeCallExpression = (
const type: ValueType | undefined = ctx.scope[callee.name];
if (!type) {
throw new Error(
`I was expecting "${callee.name}" to be a type in scope; maybe it's not spelled correctly.`
`I was expecting "${callee.name}" to be a function or type in scope; maybe it's not spelled correctly.`
);
}
calleeType = type;
Expand Down
44 changes: 41 additions & 3 deletions packages/proto-compiler/src/coreLibrary.ts
@@ -1,5 +1,6 @@
import makeLibrary from './makeLibrary';
import { CauseError } from './runtime';
import { CoreFunctionValueType, LibraryValueType } from './analyzer';
import makeLibrary, { Library, mergeLibraries } from './makeLibrary';
import { CauseError, EffectHandler } from './runtime';

const coreLibrary = makeLibrary(
{
Expand All @@ -21,4 +22,41 @@ const coreLibrary = makeLibrary(
export const LogEffectSymbol = coreLibrary.symbols['Log'];
export const PanicEffectSymbol = coreLibrary.symbols['Panic'];

export default coreLibrary;
type CoreFnMap = { [name: string]: Function };

const coreFunctions: CoreFnMap = {
append: (x: string, y: string) => {
return x + y;
},
};

export interface CoreLibrary {
runtimeScope: Record<string, symbol | Function>;
analyzerScope: Record<string, LibraryValueType | CoreFunctionValueType>;
handleEffects: EffectHandler;
}

export function mergeCoreLibrary(...libraries: Library[]): CoreLibrary {
const extensionLibrary = mergeLibraries(coreLibrary, ...libraries);
return {
runtimeScope: {
...coreFunctions,
...extensionLibrary.symbols,
},
analyzerScope: {
...Object.fromEntries(
Object.entries(coreFunctions).map(([k, v]) => [
k,
{
kind: 'coreFn',
name: k,
} as CoreFunctionValueType,
])
),
...extensionLibrary.analyzerScope,
},
handleEffects: extensionLibrary.handleEffects,
};
}

export default mergeCoreLibrary();
7 changes: 7 additions & 0 deletions packages/proto-compiler/src/generator.ts
Expand Up @@ -160,6 +160,13 @@ const generateCallExpression = (
),
true
);
} else if (type.kind === 'coreFn') {
return jsAst.callExpression(
generateExpression(node.callee, [...breadcrumbs, 'callee'], ctx),
node.parameters.map((a, i) =>
generateExpression(a, [...breadcrumbs, 'parameters', i], ctx)
)
);
} else {
throw new Error(
`I don't know how to compile this kind of function call yet. The type of the callee is ${JSON.stringify(
Expand Down
2 changes: 1 addition & 1 deletion packages/proto-compiler/src/makeLibrary.ts
Expand Up @@ -16,7 +16,7 @@ export type LibraryItem = TypeLibraryItem | EffectLibraryItem;

export interface Library {
symbols: LibrarySymbolMap;
analyzerScope: analyzer.Scope;
analyzerScope: Record<string, analyzer.LibraryValueType>;
handleEffects: EffectHandler;
}

Expand Down
8 changes: 4 additions & 4 deletions packages/proto-compiler/src/runtime.ts
@@ -1,5 +1,5 @@
import * as vm from 'vm';
import coreLibrary from './coreLibrary';
import coreLibrary, { CoreLibrary, mergeCoreLibrary } from './coreLibrary';
import { emptyLibrary, Library, mergeLibraries } from './makeLibrary';

export type EffectHandler = (
Expand All @@ -25,14 +25,14 @@ export interface CauseRuntimeInvokeOptions {

export class CauseRuntime {
script: vm.Script;
library: Library;
library: CoreLibrary;

constructor(jsSource: string, filename: string, opts?: CauseRuntimeOptions) {
this.script = new vm.Script(jsSource, {
filename,
});

this.library = mergeLibraries(coreLibrary, opts?.library ?? emptyLibrary);
this.library = mergeCoreLibrary(opts?.library ?? emptyLibrary);
}

async invokeFn(
Expand Down Expand Up @@ -73,7 +73,7 @@ export class CauseRuntime {
}

invokeFnAsGenerator(name: string, params: unknown[]): Generator {
const context = this.library.symbols;
const context = this.library.runtimeScope;

this.script.runInNewContext(context, {
breakOnSigint: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/proto-compiler/src/tests/io.spec.ts
@@ -1,7 +1,7 @@
import makeLibrary from '../makeLibrary';
import { runMainSync } from './testRunner';

it.skip('can receive a value from an input effect and return it', () => {
it('can receive a value from an input effect and return it', () => {
const script = `
fn main() {
cause Log("What is your name?")
Expand Down

0 comments on commit 8ac0a5d

Please sign in to comment.