Skip to content
This repository has been archived by the owner on Nov 5, 2024. It is now read-only.

Commit

Permalink
refactor: move all code analysis/runtime elements into a new class, P…
Browse files Browse the repository at this point in the history
…Host
  • Loading branch information
R-unic committed Oct 7, 2023
1 parent d851e12 commit 1d7f28d
Show file tree
Hide file tree
Showing 12 changed files with 72 additions and 58 deletions.
8 changes: 3 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"displayName": "PLang",
"icon": "https://avatars.githubusercontent.com/u/146694713?s=400&u=4e01b5afefbf7e40641702e5cbdf785ff183fe35&v=4",
"main": "dist/src/main.js",
"bin": { "pint": "dist/tools/pint.js" },
"bin": {
"pint": "dist/tools/pint.js"
},
"scripts": {
"test": "mocha dist/src/unit-tests -j 4 --extension js",
"build": "tsc --skipLibCheck",
Expand Down
9 changes: 4 additions & 5 deletions src/runtime/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { fakeToken, getIntrinsicExtension } from "../utility";
import { INTRINSIC_EXTENDED_LITERAL_VALUE_TYPES } from "../code-analysis/type-checker/types/type-sets";
import type Binder from "../code-analysis/type-checker/binder";
import type Resolver from "../code-analysis/resolver";
import type P from "../../tools/p";
import Syntax from "../code-analysis/tokenization/syntax-type";
import Scope from "./scope";
import PFunction from "./values/function";
import HookedException from "./hooked-exceptions";
import Intrinsics from "./intrinsics";
import Syntax from "../code-analysis/tokenization/syntax-type";
import PFunction from "./values/function";
import AST from "../code-analysis/parser/ast";
import P from "../../tools/p";

import { LiteralExpression } from "../code-analysis/parser/ast/expressions/literal";
import type { StringInterpolationExpression } from "../code-analysis/parser/ast/expressions/string-interpolation";
Expand All @@ -37,7 +37,6 @@ import type { IfStatement } from "../code-analysis/parser/ast/statements/if";
import type { WhileStatement } from "../code-analysis/parser/ast/statements/while";
import type { FunctionDeclarationStatement } from "../code-analysis/parser/ast/statements/function-declaration";
import type { ReturnStatement } from "../code-analysis/parser/ast/statements/return";
import Intrinsic from "./values/intrinsic";

const MAX_RECURSION_DEPTH = 1200;

Expand All @@ -50,7 +49,7 @@ export default class Interpreter implements AST.Visitor.Expression<ValueType>, A
private readonly intrinsics = new Intrinsics(this);

public constructor(
public readonly runner: P,
public readonly host: P,
public readonly resolver: Resolver,
public readonly binder: Binder,
public fileName = "unnamed"
Expand Down
8 changes: 4 additions & 4 deletions src/runtime/intrinsics/eval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ export default class Eval extends Intrinsic.Function {
public readonly argumentTypes = { code: new SingularType("string") };

public call(code: string): ValueType {
const enclosingResultOutputEnabled = this.interpreter!.runner.executionOptions.outputResult;
this.interpreter!.runner.executionOptions.outputResult = false;
const result = this.interpreter!.runner.doString(code);
this.interpreter!.runner.executionOptions.outputResult = enclosingResultOutputEnabled;
const enclosingResultOutputEnabled = this.interpreter!.host.executionOptions.outputResult;
this.interpreter!.host.executionOptions.outputResult = false;
const result = this.interpreter!.host.doString(code);
this.interpreter!.host.executionOptions.outputResult = enclosingResultOutputEnabled;
return result;
}
}
2 changes: 1 addition & 1 deletion src/runtime/intrinsics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default class Intrinsics {
) {}

public inject(): void {
this.define("version$", this.interpreter.runner.version, new SingularType("string"));
this.define("version$", this.interpreter.host.version, new SingularType("string"));
this.define("filename$", this.interpreter.fileName, new SingularType("string"));
this.define("dirname$", path.dirname(this.interpreter.fileName), new SingularType("string"));
this.define("argv", argv.slice(3), new ArrayType(new SingularType("string")));
Expand Down
2 changes: 1 addition & 1 deletion src/unit-tests/binder-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function bind(source: string): BoundStatement[] {
const p = new P("test");
const parser = p.createParser(source);
const ast = parser.parse();
return p.binder.bindStatements(ast);
return p.host.binder.bindStatements(ast);
}

const testDirectory = "./tests/";
Expand Down
2 changes: 1 addition & 1 deletion src/unit-tests/interpreter-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ let p = new P("test");
function evaluate(source: string, createNewEnvironment = true): ValueType {
const result = p.doString(source);
if (createNewEnvironment)
p.refreshResources();
p.newHost();

return result;
}
Expand Down
2 changes: 1 addition & 1 deletion src/unit-tests/resolver-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function getResolveFunction(source: string): () => void {
const p = new P("test");
const parser = p.createParser(source);
const ast = parser.parse();
return () => p.resolver.resolve(ast);
return () => p.host.resolver.resolve(ast);
}

const testDirectory = "./tests/";
Expand Down
6 changes: 3 additions & 3 deletions src/unit-tests/type-checker-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ function getCheckFunction(source: string): () => void {
const p = new P("test");
const parser = p.createParser(source);
const ast = parser.parse();
p.resolver.resolve(ast);
const boundAST = p.binder.bindStatements(ast);
return () => p.typeChecker.check(boundAST);
p.host.resolver.resolve(ast);
const boundAST = p.host.binder.bindStatements(ast);
return () => p.host.typeChecker.check(boundAST);
}

const testDirectory = "./tests/";
Expand Down
3 changes: 1 addition & 2 deletions tools/classes/ast-viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import reader from "readline-sync";
import { BoundNode } from "../../src/code-analysis/type-checker/binder/bound-node";
import { Type } from "../../src/code-analysis/type-checker/types/type";
import type P from "../p";
import Parser from "../../src/code-analysis/parser";
import AST from "../../src/code-analysis/parser/ast";

namespace ASTViewer {
Expand All @@ -17,7 +16,7 @@ namespace ASTViewer {
const parser = p.createParser(source);
const ast = parser.parse();
if (option === "bound") {
const boundAST = p.binder.bindStatements(ast);
const boundAST = p.host.binder.bindStatements(ast);
viewNodeList(boundAST);
}
else
Expand Down
32 changes: 32 additions & 0 deletions tools/classes/p-host.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { TypeChecker } from "../../src/code-analysis/type-checker";
import type P from "../p";
import Lexer from "../../src/code-analysis/tokenization/lexer";
import TypeTracker from "../../src/code-analysis/parser/type-tracker";
import TypeAnalyzer from "../../src/code-analysis/parser/type-analyzer";
import Parser from "../../src/code-analysis/parser";
import Resolver from "../../src/code-analysis/resolver";
import Binder from "../../src/code-analysis/type-checker/binder";
import Interpreter from "../../src/runtime/interpreter";

export default class PHost {
private typeTracker = new TypeTracker;
public resolver = new Resolver;
public binder = new Binder;
public typeChecker = new TypeChecker;
public interpreter: Interpreter;

public constructor(
private readonly runner: P,
fileName?: string
) {
this.interpreter = new Interpreter(runner, this.resolver, this.binder, fileName)
}

public createParser(source: string): Parser {
const lexer = new Lexer(source);
const tokens = lexer.tokenize();
const typeAnalyzer = new TypeAnalyzer(tokens, this.typeTracker);
typeAnalyzer.analyze();
return new Parser(tokens, typeAnalyzer, this.runner);
}
}
52 changes: 18 additions & 34 deletions tools/p.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,9 @@ import { readFileSync } from "fs";
import util from "util";
import "colors.ts";

import { TypeChecker, ValueType } from "../src/code-analysis/type-checker";
import Lexer from "../src/code-analysis/tokenization/lexer";
import TypeTracker from "../src/code-analysis/parser/type-tracker";
import TypeAnalyzer from "../src/code-analysis/parser/type-analyzer";
import type { ValueType } from "../src/code-analysis/type-checker";
import PHost from "./classes/p-host";
import Parser from "../src/code-analysis/parser";
import Binder from "../src/code-analysis/type-checker/binder";
import Resolver from "../src/code-analysis/resolver";
import Interpreter from "../src/runtime/interpreter";
import PValue from "../src/runtime/values/value";
import REPL from "./classes/repl";
import pkg = require("../package.json");
Expand All @@ -22,12 +17,7 @@ interface PExecutionOptions {
}

export default class P {
private typeTracker = new TypeTracker;

public resolver = new Resolver;
public binder = new Binder;
public typeChecker = new TypeChecker;
public interpreter: Interpreter;
public host: PHost;
public readonly repl = new REPL(this);
public readonly version = "v" + pkg.version;
public readonly executionOptions: PExecutionOptions = {
Expand All @@ -37,16 +27,10 @@ export default class P {
outputResult: false
};

public constructor(fileName?: string) {
this.interpreter = new Interpreter(this, this.resolver, this.binder, fileName)
}

public createParser(source: string): Parser {
const lexer = new Lexer(source);
const tokens = lexer.tokenize();
const typeAnalyzer = new TypeAnalyzer(tokens, this.typeTracker);
typeAnalyzer.analyze();
return new Parser(tokens, typeAnalyzer, this);
public constructor(
private readonly fileName?: string
) {
this.host = new PHost(this, fileName);
}

public doString(source: string): ValueType {
Expand All @@ -58,13 +42,13 @@ export default class P {
if (this.executionOptions.outputAST)
console.log(ast.toString());

this.resolver.resolve(ast);
const boundAST = this.binder.bindStatements(ast);
this.host.resolver.resolve(ast);
const boundAST = this.host.binder.bindStatements(ast);
if (this.executionOptions.outputBoundAST)
console.log(boundAST.toString());

this.typeChecker.check(boundAST);
const result = this.interpreter.evaluate(ast);
this.host.typeChecker.check(boundAST);
const result = this.host.interpreter.evaluate(ast);

if (this.executionOptions.outputResult) {
const stringified = result instanceof PValue ?
Expand All @@ -80,15 +64,15 @@ export default class P {
public doFile(filePath: string): ValueType {
const fileContents = readFileSync(filePath, "utf-8");
const result = this.doString(fileContents);
this.refreshResources();
this.newHost();
return result;
}

public refreshResources(): void {
this.typeTracker = new TypeTracker;
this.binder = new Binder;
this.resolver = new Resolver;
this.typeChecker = new TypeChecker;
this.interpreter = new Interpreter(this, this.resolver, this.binder, this.interpreter.fileName);
public createParser(source: string): Parser {
return this.host.createParser(source);
}

public newHost(): void {
this.host = new PHost(this, this.fileName);
}
}

0 comments on commit 1d7f28d

Please sign in to comment.