Socket
Socket
Sign inDemoInstall

gravlax

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gravlax - npm Package Compare versions

Comparing version 0.11.0 to 0.11.1

239

lib/interpreter.js

@@ -1,5 +0,1 @@

import {
visitExpr,
visitStmt
} from "./ast.js";
import { LoxCallable } from "./callable.js";

@@ -12,17 +8,5 @@ import { Environment } from "./environment.js";

import { runtimeError } from "./main.js";
class ClockFn extends LoxCallable {
arity() {
return 0;
}
call() {
return Date.now();
}
toString() {
return "<native fn>";
}
}
class ReturnCall extends Error {
class ReturnCall {
value;
constructor(value) {
super();
this.value = value;

@@ -48,2 +32,5 @@ }

}
function assertUnreachable(x) {
throw new Error(`Unreachable code reached! ${x}`);
}
class Interpreter {

@@ -54,14 +41,15 @@ globals = new Environment();

constructor() {
this.globals.define("clock", new ClockFn());
this.globals.define(
"clock",
// Can't use an object literal here because it must be instanceof LoxCallable.
new class extends LoxCallable {
arity = () => 0;
call = () => Date.now();
toString = () => "<native fn>";
}()
);
}
return(stmt) {
const value = stmt.value && this.evaluate(stmt.value);
throw new ReturnCall(value);
}
resolve(expr, depth) {
this.#locals.set(expr, depth);
}
"var-expr"(expr) {
return this.#lookUpVariable(expr.name, expr);
}
#lookUpVariable(name, expr) {

@@ -74,19 +62,2 @@ const distance = this.#locals.get(expr);

}
"var-stmt"(stmt) {
let value = null;
if (stmt.initializer) {
value = this.evaluate(stmt.initializer);
}
this.#environment.define(stmt.name.lexeme, value);
}
assign(expr) {
const value = this.evaluate(expr.value);
const distance = this.#locals.get(expr);
if (distance !== void 0) {
this.#environment.assignAt(distance, expr.name, value);
} else {
this.globals.assign(expr.name, value);
}
return value;
}
binary(expr) {

@@ -145,5 +116,2 @@ const left = this.evaluate(expr.left);

}
block(block) {
this.executeBlock(block.statements, new Environment(this.#environment));
}
call(expr) {

@@ -181,9 +149,111 @@ const callee = this.evaluate(expr.callee);

evaluate(expr) {
return visitExpr(expr, this);
switch (expr.kind) {
case "assign":
const value = this.evaluate(expr.value);
const distance = this.#locals.get(expr);
if (distance !== void 0) {
this.#environment.assignAt(distance, expr.name, value);
} else {
this.globals.assign(expr.name, value);
}
return value;
case "binary":
return this.binary(expr);
case "call":
return this.call(expr);
case "get": {
const obj = this.evaluate(expr.object);
if (obj instanceof LoxInstance) {
return obj.get(expr.name);
}
throw new RuntimeError(expr.name, "Only instances have properties.");
}
case "grouping":
return this.evaluate(expr.expr);
case "literal":
return expr.value;
case "logical":
const left = this.evaluate(expr.left);
if (expr.operator.type == "or") {
if (isTruthy(left)) {
return left;
}
} else {
if (!isTruthy(left)) {
return left;
}
}
return this.evaluate(expr.right);
case "set": {
const obj = this.evaluate(expr.object);
if (!(obj instanceof LoxInstance)) {
throw new RuntimeError(expr.name, "Only instances have fields.");
}
const value2 = this.evaluate(expr.value);
obj.set(expr.name, value2);
return value2;
}
case "unary":
const right = this.evaluate(expr.right);
switch (expr.operator.type) {
case "-":
checkNumberOrCurrencyOperand(expr.operator, right);
return applyToNumOrCurrency(right, (v) => -v);
case "!":
return !isTruthy(right);
}
throw new Error(`Unknown unary type ${expr.operator.type}`);
case "this":
return this.#lookUpVariable(expr.keyword, expr);
case "var-expr":
return this.#lookUpVariable(expr.name, expr);
}
}
this(expr) {
return this.#lookUpVariable(expr.keyword, expr);
}
execute(stmt) {
visitStmt(stmt, this);
switch (stmt.kind) {
case "block":
this.executeBlock(stmt.statements, new Environment(this.#environment));
break;
case "class":
this.class(stmt);
break;
case "expr":
this.evaluate(stmt.expression);
break;
case "func":
const func = new LoxFunction(stmt, this.#environment, false);
this.#environment.define(stmt.name.lexeme, func);
break;
case "if":
if (isTruthy(this.evaluate(stmt.condition))) {
this.execute(stmt.thenBranch);
} else if (stmt.elseBranch !== null) {
this.execute(stmt.elseBranch);
}
break;
case "print": {
const value = this.evaluate(stmt.expression);
console.log(stringify(value));
break;
}
case "return": {
const value = stmt.value && this.evaluate(stmt.value);
throw new ReturnCall(value);
}
case "var-stmt": {
let value = null;
if (stmt.initializer) {
value = this.evaluate(stmt.initializer);
}
this.#environment.define(stmt.name.lexeme, value);
break;
}
case "while":
while (isTruthy(this.evaluate(stmt.condition))) {
this.execute(stmt.body);
}
break;
default:
assertUnreachable(stmt);
}
}

@@ -201,26 +271,2 @@ executeBlock(stmts, environment) {

}
expr(stmt) {
this.evaluate(stmt.expression);
}
func(stmt) {
const func = new LoxFunction(stmt, this.#environment, false);
this.#environment.define(stmt.name.lexeme, func);
}
get(expr) {
const obj = this.evaluate(expr.object);
if (obj instanceof LoxInstance) {
return obj.get(expr.name);
}
throw new RuntimeError(expr.name, "Only instances have properties.");
}
grouping(expr) {
return this.evaluate(expr.expr);
}
if(stmt) {
if (isTruthy(this.evaluate(stmt.condition))) {
this.execute(stmt.thenBranch);
} else if (stmt.elseBranch !== null) {
this.execute(stmt.elseBranch);
}
}
interpret(statements) {

@@ -237,47 +283,2 @@ try {

}
literal(expr) {
return expr.value;
}
logical(expr) {
const left = this.evaluate(expr.left);
if (expr.operator.type == "or") {
if (isTruthy(left)) {
return left;
}
} else {
if (!isTruthy(left)) {
return left;
}
}
return this.evaluate(expr.right);
}
print(stmt) {
const value = this.evaluate(stmt.expression);
console.log(stringify(value));
}
set(expr) {
const obj = this.evaluate(expr.object);
if (!(obj instanceof LoxInstance)) {
throw new RuntimeError(expr.name, "Only instances have fields.");
}
const value = this.evaluate(expr.value);
obj.set(expr.name, value);
return value;
}
unary(expr) {
const right = this.evaluate(expr.right);
switch (expr.operator.type) {
case "-":
checkNumberOrCurrencyOperand(expr.operator, right);
return applyToNumOrCurrency(right, (v) => -v);
case "!":
return !isTruthy(right);
}
throw new Error(`Unknown unary type ${expr.operator.type}`);
}
while(stmt) {
while (isTruthy(this.evaluate(stmt.condition))) {
this.execute(stmt.body);
}
}
}

@@ -284,0 +285,0 @@ class RuntimeError extends Error {

{
"name": "gravlax",
"version": "0.11.0",
"version": "0.11.1",
"description": "A Lox interpreter with tasty TypeScript seasoning",

@@ -23,2 +23,3 @@ "repository": {

"scripts": {
"benchmark": "pnpm --silent run repl bench/fib33.lox",
"build": "tsup",

@@ -72,3 +73,3 @@ "coverage": "pnpm test -- --coverage --no-watch",

"markdownlint": "^0.33.0",
"markdownlint-cli": "^0.38.0",
"markdownlint-cli": "^0.39.0",
"npm-package-json-lint": "^7.1.0",

@@ -75,0 +76,0 @@ "npm-package-json-lint-config-default": "^6.0.0",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc