Skip to content

Commit

Permalink
feat: parser for connect - pass - read|save
Browse files Browse the repository at this point in the history
  • Loading branch information
albertolerda committed Oct 3, 2023
1 parent 3143dc2 commit e2210d9
Show file tree
Hide file tree
Showing 13 changed files with 3,694 additions and 644 deletions.
2 changes: 0 additions & 2 deletions pkg/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
export * from '@slangroom/core/plugin';
export * from '@slangroom/core/slangroom';
37 changes: 19 additions & 18 deletions pkg/core/src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ const Parser = new (class extends CstParser {
});

#statement = this.RULE('statement', () => {
this.OPTION(() => this.SUBRULE(this.#connect));
this.OPTION(() => this.SUBRULE(this.#sendpass));
this.OPTION1(() => this.SUBRULE(this.#connect));
this.MANY(() => {
this.SUBRULE(this.#sendpass);
});
this.SUBRULE(this.#readsave);
});

Expand All @@ -41,22 +43,17 @@ const Parser = new (class extends CstParser {
});

#sendpass = this.RULE('sendpass', () => {
this.AT_LEAST_ONE_SEP({
SEP: And,
DEF() {
this.OR([
{
ALT: () => this.CONSUME(Send),
},
{
Alt: () => this.CONSUME(Pass),
},
]);
this.OPTION(() => this.SUBRULE(this.#buzzwords));
this.CONSUME(Identifier);
this.CONSUME(And);
this.OR([
{
ALT: () => this.CONSUME(Send),
},
});
{
ALT: () => this.CONSUME(Pass),
},
]);
this.OPTION(() => this.SUBRULE(this.#buzzwords));
this.CONSUME(Identifier);
this.CONSUME(And);
});

#readsave = this.RULE('readsave', () => {
Expand All @@ -70,6 +67,7 @@ const Parser = new (class extends CstParser {

#read = this.RULE('read', () => {
this.CONSUME(Read);
this.SUBRULE(this.#buzzwords);
this.OPTION(() => this.SUBRULE(this.#into));
});

Expand All @@ -93,5 +91,8 @@ export const CstVisitor = Parser.getBaseCstVisitorConstructor();

export const parse = (tokens: IToken[]) => {
Parser.input = tokens;
return Parser.statement();

const res = Parser.statements();
console.log(Parser.errors)
return res
};
86 changes: 23 additions & 63 deletions pkg/core/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Jsonable, JsonableObject, ZenroomParams } from '@slangroom/shared';
import { Action } from '@slangroom/core/visitor';

export class ExecContext {
#store = new Map<any, any>();
Expand All @@ -17,7 +16,7 @@ export class ExecParams {
#data: JsonableObject;
#keys: JsonableObject;

contsructor(params: ZenroomParams) {
constructor(params: ZenroomParams) {
this.#data = params.data || {};
this.#keys = params.keys || {};
}
Expand All @@ -29,77 +28,38 @@ export class ExecParams {
set(key: string, value: Jsonable) {
this.#data[key] = value;
}
}

export abstract class Plugin {
#phrase: string;

constructor(phrase: string) {
this.#phrase = phrase.toLowerCase();
}

match(actn: Action) {
return actn.phrase.toLowerCase() === this.#phrase;
}

abstract execute(params: ExecParams, ctx: ExecContext): void | Promise<void>;
}

export class ConnectPlugin extends Plugin {
#execute: (params: ExecParams, ctx: ExecContext) => void;
constructor(phrase: string, cb: (params: ExecParams, ctx: ExecContext) => void) {
super(phrase);
// TODO: using `phrase`, fetch all the variables and put them inside
// `ExecParams`.
this.#execute = cb;
}

execute(params: ExecParams, ctx: ExecContext) {
this.#execute(params, ctx);
}
}

export class ReadPlugin extends Plugin {
#execute: (params: ExecParams, ctx: ExecContext) => void;

constructor(phrase: string, cb: (params: ExecParams, ctx: ExecContext) => void) {
super(phrase);
// TODO: using `phrase`, fetch all the variables and put them inside
// `ExecParams`.
this.#execute = cb;
getKeys() {
return this.#keys
}

execute(params: ExecParams, ctx: ExecContext) {
this.#execute(params, ctx);
getData() {
return this.#data
}
}

export class IntoPlugin extends Plugin {
#execute: (params: ExecParams) => void;
export class ReadPlugin {
#phrase: string;
#params: string[];
#func: (...args: Jsonable[]) => Jsonable;

constructor(phrase: string, cb: (params: ExecParams) => void) {
super(phrase);
// TODO: using `phrase`, fetch all the variables and put them inside
// `ExecParams`.
this.#execute = cb;
constructor(phrase: string, params: string[], func: (...args: Jsonable[]) => Jsonable) {
this.#phrase = phrase;
this.#params = params
this.#func = func;
}

execute(params: ExecParams) {
this.#execute(params);
execute(execParams: ExecParams) {
const args = this.#params.map((v: any) => execParams.get(v))
if(args.some(v => v == undefined)) {
throw new Error("Some arguments are undefined") // TODO: we can do
// this befone executing the statement
} else {
return this.#func(...args.map(v => v || ""))
}
}
}

export class SavePlugin extends Plugin {
#execute: (params: ExecParams) => void;

constructor(phrase: string, cb: (params: ExecParams) => void) {
super(phrase);
// TODO: using `phrase`, fetch all the variables and put them inside
// `ExecParams`.
this.#execute = cb;
}

execute(params: ExecParams) {
this.#execute(params);
getPhrase() {
return this.#phrase
}
}
82 changes: 16 additions & 66 deletions pkg/core/src/slangroom.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,31 @@
import { getIgnoredStatements } from '@slangroom/ignored';
//import { getIgnoredStatements } from '@slangroom/ignored';
import { ZenroomParams, zencodeExec } from '@slangroom/shared';
import {
Plugin,
ExecContext,
ExecParams,
ReadPlugin,
SavePlugin,
ConnectPlugin,
} from '@slangroom/core/plugin';
import { lex } from '@slangroom/core/lexer';
import { parse } from '@slangroom/core/parser';
import { StatementType, visit, type Statement } from '@slangroom/core/visitor';
//import { lex } from '@slangroom/core/lexer';
//import { parse } from '@slangroom/core/parser';
//import { visit, type Statement } from '@slangroom/core/visitor';

type Plugins = Plugin | Set<Plugin> | Array<Plugin | Set<Plugin>>;

export class Slangroom {
#readPlugins = new Set<ReadPlugin>();
#savePlugins = new Set<SavePlugin>();
#connectPlugins = new Set<ConnectPlugin>();
#readPlugins = new Map<string, ReadPlugin>();

constructor(first: Plugins, ...rest: Plugins[]) {
const recurse = (x: Plugins) => {
if (Array.isArray(x) || x instanceof Set) x.forEach(recurse);
else {
if (x instanceof ReadPlugin) this.#readPlugins.add(x);
if (x instanceof SavePlugin) this.#savePlugins.add(x);
if (x instanceof ConnectPlugin) this.#connectPlugins.add(x);
if (x instanceof ReadPlugin) this.#readPlugins.set(x.getPhrase(), x);
}
};
[first, ...rest].forEach(recurse);
}

async execute(contract: string, zparams: ZenroomParams) {
const ignoreds = await getIgnoredStatements(contract, zparams);
const { givens, whens, thens } = ignoreds.reduce(
//const ignoreds = await getIgnoredStatements(contract, zparams);
/*const { givens, thens } = ignoreds.reduce(
(acc, cur) => {
const given = cur.split(/^\s*given\s+i\s+/i);
if (given[1]) {
Expand All @@ -52,69 +44,27 @@ export class Slangroom {
return acc;
},
{ givens: [] as Statement[], whens: [] as Statement[], thens: [] as Statement[] }
);
);*/

const params = new ExecParams(zparams);
const ctx = new ExecContext();

for (const [i, g] of givens.entries()) {
if (g.type == StatementType.Connect) {
const connectPlugin = [...this.#connectPlugins].find((x) => x.match(g.connect));
if (!connectPlugin) continue;
givens.splice(i, 1);
connectPlugin.execute(params, ctx);
} else if (g.type === StatementType.Read) {
const readPlugin = [...this.#readPlugins].find((x) => x.match(g.read));
if (!readPlugin) continue;
givens.splice(i, 1);
readPlugin.execute(params, ctx);
} else if (g.type === StatementType.ReadAndSave) {
const readPlugin = [...this.#readPlugins].find((x) => x.match(g.read));
if (!readPlugin) continue;
const savePlugin = [...this.#savePlugins].find((x) => x.match(g.save));
if (!savePlugin) continue;
// TODO: somehow link theso two: make execute() return a
// JsonableObject
readPlugin.execute(params, ctx);
savePlugin.execute(params);
} else if (g.type === StatementType.ReadInto) {
const readPlugin = [...this.#readPlugins].find((x) => x.match(g.read));
if (!readPlugin) continue;
// const into = g.into;
// TODO: use `into` with `params`
givens.splice(i, 1);
readPlugin.execute(params, ctx);
} else if (g.type === StatementType.ReadIntoWithin) {
const readPlugin = [...this.#readPlugins].find((x) => x.match(g.read));
if (!readPlugin) continue;
// const into = g.into;
// const within = g.within;
// TODO: use `into` with `params`
givens.splice(i, 1);
readPlugin.execute(params, ctx);
}
}

for (const w of whens) {
for (const p of this.#plugins) {
if (p.match(w)) p.execute(ctx);
}
}
/*for (const [i, g] of givens.entries()) {
}*/

const zout = await zencodeExec(contract, params);
const zout = await zencodeExec(contract, {keys: params.getKeys(), data: params.getData()});

for (const t of thens) {
/*for (const t of thens) {
for (const p of this.#plugins) {
if (p.match(t)) p.execute(ctx);
}
}
}*/

return zout;
}
}

const astify = (line: string) => {
/*const astify = (line: string) => {
const { tokens } = lex(line);
const cst = parse(tokens);
return visit(cst);
};
};*/
2 changes: 1 addition & 1 deletion pkg/core/src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const allTokens = [
And,
To,
Identifier,
Buzzword,
Send,
Pass,
Buzzword,
];
Loading

0 comments on commit e2210d9

Please sign in to comment.