Skip to content

Commit

Permalink
ethereum connect
Browse files Browse the repository at this point in the history
For the moment I am using one file for each verb (e.g. read.ts and connect.ts).
The result is that connect is a parser that matches only one sentence.
  • Loading branch information
albertolerda committed Sep 29, 2023
1 parent 76a8d3e commit 0add251
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 1 deletion.
96 changes: 96 additions & 0 deletions pkg/ethereum/src/connect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { createToken, Lexer, CstParser } from "@slangroom/deps/chevrotain";
import { JsonableObject } from "@slangroom/shared";
import { StmtContext } from "@slangroom/core/slangroom";
import { Whitespace, Identifier } from "@slangroom/shared/tokens"
import { Web3 } from 'web3'

type EthereumConnect = {
address: string
}

const Ethereum = createToken({
name: "Ethereum",
pattern: /ethereum/i,
});
const The = createToken({
name: "The",
pattern: /the/i,
group: Lexer.SKIPPED,
});
const Provider = createToken({
name: "Provider",
pattern: /Provider/i,
});
const To = createToken({
name: "To",
pattern: /To/i,
});

const allTokens = [
Whitespace,
The,
To,
Ethereum,
Provider,
Identifier,
];
const StatementLexer = new Lexer(allTokens);
// ----------------- parser -----------------
class StatementParser extends CstParser {
constructor() {
super(allTokens);

this.performSelfAnalysis();
}

public statement = this.RULE("statement", () => {
this.CONSUME(To);
this.CONSUME(Ethereum);
this.CONSUME(Provider);
this.CONSUME(Identifier);
});
}

const parser = new StatementParser();
// ----------------- Interpreter -----------------
const BaseCstVisitor = parser.getBaseCstVisitorConstructor();

class StatementInterpreter extends BaseCstVisitor {
constructor() {
super();
this.validateVisitor();
}
statement(ctx: any) {
return {address: ctx.Identifier[0].image.slice(1,-1)}
}
}

// We only need a single interpreter instance because our interpreter has no state.
const interpreter = new StatementInterpreter();


export const line2Ast = (text: string) => {
const lexResult = StatementLexer.tokenize(text);
parser.input = lexResult.tokens;
const cst = parser.statement();
const value = interpreter.visit(cst);
return {
value: value,
lexResult: lexResult,
parseErrors: parser.errors,
};
}

type EthereumConnectResult = {
name: string,
value: Web3
}

export const evaluate = async (ast: EthereumConnect,
keys: JsonableObject, stmtCtx: StmtContext): Promise<EthereumConnectResult> => {
const address = (keys[ast.address] || stmtCtx.data[ast.address] || ast.address) as string
return {
name: "web3",
value: new Web3(address)
}
}
7 changes: 6 additions & 1 deletion pkg/ethereum/test/read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import { Web3 } from 'web3'
const test = anyTest as TestFn<{web3: Web3}>;

import { EthereumRequestKind, line2Ast, evaluate } from '@slangroom/ethereum/read';
import { line2Ast as line2AstConnect, evaluate as evaluateConnect } from '@slangroom/ethereum/connect';

test.before(async (t) => {
t.context.web3 = new Web3('http://78.47.38.223:9485')
const ast = line2AstConnect("to the ethereum provider 'foo'");
t.deepEqual(ast.value, { address: 'foo' })
const res = await evaluateConnect(ast.value, {}, {data: {foo: "http://78.47.38.223:9485"}, context: t.context})
t.is(res.name, "web3")
t.context.web3 = res.value
});

test("Ethereum nonce", async (t) => {
Expand Down

0 comments on commit 0add251

Please sign in to comment.