npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gravlax

v0.13.1

Published

A Lox interpreter with tasty TypeScript seasoning

Downloads

15

Readme

This is my implementation of an interpreter for the Lox language from Robert Nystrom's Crafting Interpreters. I'm building this as part of my Winter 2024 batch at the Recurse Center.

Usage

npx gravlax [file.lox]

Departures from the book

Features not in the book

There's one notable feature I added beyond what's in the text of Crafting Interpreters: support for commas as numeric separators and currencies as first-class values.

You can write 1,234 + 2,456 and gravlax will happily print out 3690. Note that this has the… interesting side effect of making the grammar whitespace-sensitive: f(1,2) and f(1, 2) parse differently (the former is a one-argument call).

You can also write out currency values like $123 or €456 and do math on them. The operations you'd expect to work will work: adding or subtracting values from the same currency is OK, multiply a currency by a scalar is OK, etc:

> ($1,234 + $2,345) / 10
$357.9
> $12 + €23
MixedCurrencyError: Operands must be the same currency.

Two other niceties:

  1. Support for expressions in the REPL (Chapter 8 Challenge 1). If you run npx gravlax and then 1+2, it will print 3. No need to write a print statement. This makes it possible to use gravlax as a calculator.

  2. The REPL uses readline so you can hit up arrow to get the previous expression and edit it.

Implementation details

Rather than representing AST nodes as classes, I used TypeScript interfaces and a discriminated union for Expr and Stmt. This means that we don't need a codegen step. It also means that we don't need the visitor pattern: pattern-matching with switch/case is more idiomatic and less code.

While I used a class for the Scanner (same as the book), I used a closure for the parser. Mostly this just means less writing this dot whatever.

Performance

On my machine, gravlax runs the Fibonacci code from Chapter 14 in ~3 minutes (174 seconds). Compare this with 27s for jlox. So we're ~6x slower than Java.

In jlox and gravlax, returning from a function is implemented by throwing an exception. It's critical that this class not derive from Error, so that it doesn't carry along stack traces:

- class ReturnCall extends Error {
+ class ReturnCall {

The latter winds up being ~10x faster than the former. This is the JS equivalent of the weird super(null, null, false, false) call in jlox. See #37.

Development

pnpm install
pnpm test
pnpm repl

Contributors

💙 This package was templated with create-typescript-app.