Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

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.7.0 to 0.8.0

lib/callable.js

11

lib/ast-printer.js

@@ -12,3 +12,9 @@ import {

),
call: (expr) => parenthesize(expr.callee, ...expr.args),
expr: (stmt) => visitExpr(stmt.expression, astPrinter),
func: (stmt) => parenthesizeText(
"func",
parenthesizeText(stmt.name.lexeme, ...stmt.params.map((p) => p.lexeme)),
visitStmt({ kind: "block", statements: stmt.body }, astPrinter)
),
grouping: (expr) => parenthesize("group", expr.expr),

@@ -24,2 +30,3 @@ if: (stmt) => parenthesizeText(

print: (stmt) => parenthesize("print", stmt.expression),
return: (stmt) => parenthesize("return", ...stmt.value ? [stmt.value] : []),
unary: (expr) => parenthesize(expr.operator.lexeme, expr.right),

@@ -41,4 +48,4 @@ "var-expr": (expr) => String(expr.name.literal),

}
function parenthesize(name, ...exprs) {
const parts = [name];
function parenthesize(...exprs) {
const parts = [];
for (const expr of exprs) {

@@ -45,0 +52,0 @@ parts.push(typeof expr == "string" ? expr : visitExpr(expr, astPrinter));

@@ -5,6 +5,34 @@ import {

} from "./ast.js";
import { LoxCallable } from "./callable.js";
import { Environment } from "./environment.js";
import { LoxFunction } from "./lox-function.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 {
value;
constructor(value) {
super();
this.value = value;
}
}
class Interpreter {
#environment = new Environment();
globals = new Environment();
#environment = this.globals;
constructor() {
this.globals.define("clock", new ClockFn());
}
return(stmt) {
const value = stmt.value && this.evaluate(stmt.value);
throw new ReturnCall(value);
}
"var-expr"(expr) {

@@ -79,2 +107,19 @@ return this.#environment.get(expr.name);

}
call(expr) {
const callee = this.evaluate(expr.callee);
const args = expr.args.map((arg) => this.evaluate(arg));
if (!(callee instanceof LoxCallable)) {
throw new RuntimeError(
expr.paren,
"Can only call functions and classes."
);
}
if (args.length != callee.arity()) {
throw new RuntimeError(
expr.paren,
`Expected ${callee.arity()} arguments but got ${args.length}.`
);
}
return callee.call(this, args);
}
evaluate(expr) {

@@ -100,2 +145,6 @@ return visitExpr(expr, this);

}
func(stmt) {
const func = new LoxFunction(stmt, this.#environment);
this.#environment.define(stmt.name.lexeme, func);
}
grouping(expr) {

@@ -186,2 +235,4 @@ return this.evaluate(expr.expr);

return "nil";
} else if (val === void 0) {
throw new Error(`undefined is not a valid Lox value`);
}

@@ -192,2 +243,3 @@ return String(val);

Interpreter,
ReturnCall,
RuntimeError,

@@ -194,0 +246,0 @@ isEqual,

@@ -59,3 +59,5 @@ import { errorOnToken } from "./main.js";

try {
if (match("var")) {
if (match("fun")) {
return func("function");
} else if (match("var")) {
return varDeclaration();

@@ -72,2 +74,19 @@ }

};
const func = (kind) => {
const name = consume("identifier", `Expect ${kind} name.`);
consume("(", "Expect '(' after ${kind} name.");
const params = [];
if (!check(")")) {
do {
if (params.length >= 255) {
error(peek(), "Can't have more than 255 parameters.");
}
params.push(consume("identifier", "Expect parameter name."));
} while (match(","));
}
consume(")", "Expect ')' after parameters.");
consume("{", `Expect '{' before ${kind} body.`);
const body = block();
return { body, kind: "func", name, params };
};
const varDeclaration = () => {

@@ -89,2 +108,4 @@ const name = consume("identifier", "Expect variable name.");

return printStatement();
} else if (match("return")) {
return returnStatement();
} else if (match("while")) {

@@ -150,2 +171,11 @@ return whileStatement();

};
const returnStatement = () => {
const keyword = previous();
let value = null;
if (!check(";")) {
value = expression();
}
consume(";", "Expect ';' after return value.");
return { keyword, kind: "return", value };
};
const block = () => {

@@ -200,4 +230,28 @@ const statements = [];

}
return primary();
return call();
};
const call = () => {
let expr = primary();
while (true) {
if (match("(")) {
expr = finishCall(expr);
} else {
break;
}
}
return expr;
};
const finishCall = (callee) => {
const args = [];
if (!check(")")) {
do {
if (args.length >= 255) {
error(peek(), "Can't have more than 255 arguments.");
}
args.push(expression());
} while (match(","));
}
const paren = consume(")", "Expect ')' after arguments.");
return { args, callee, kind: "call", paren };
};
const primary = () => {

@@ -204,0 +258,0 @@ if (match("false")) {

3

lib/scanner.js

@@ -64,3 +64,4 @@ import { error } from "./main.js";

const isCurrency = this.source[this.start] === "$";
while (isDigit(this.#peek()) || this.#peek() === ",") {
while (isDigit(this.#peek()) || // a trailing comma might be part of an argument list.
this.#peek() === "," && isDigit(this.#peekNext())) {
this.#advance();

@@ -67,0 +68,0 @@ }

{
"name": "gravlax",
"version": "0.7.0",
"version": "0.8.0",
"description": "A Lox interpreter with tasty TypeScript seasoning",

@@ -31,3 +31,3 @@ "repository": {

"lint:spelling": "cspell \"**\" \".github/**/*\"",
"pre-push": "pnpm run '/^lint(?!:packages).*$/'",
"pre-push": "pnpm run '/^(tsc|lint(?!:packages).*)$/'",
"prepare": "husky install",

@@ -34,0 +34,0 @@ "repl": "pnpm run:ts src/index.ts",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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