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

wasmpp

v1.0.1

Published

WebAssembly Text Preprocessor

Downloads

4

Readme

WebAssembly Text Preprocessor

This is the macro preprocessor for WebAssembly text language similar to the C preprocessor with some limitations and additions. The preprocessor provides inclusion wat and any data files, macro expansions, conditional compilation, and more.

(module
  (memory 1)

  (#include "lib/utils.wat")

  (#define DATA_BOTTOM 256)
  (#define COUNTER i32.const (#eval DATA_BOTTOM + (#size "text.txt")))

  (func $count
    (i32.store
      COUNTER
      (i32.add
        (i32.load COUNTER)
        i32.const 1
      )
    )
    (#ifdef DEBUG call $log)
  )

  (data (i32.const DATA_BOTTOM)
    (#include data text.txt)
  )

  (export "count" (func $count))
)

See another complete example for more details.

CLI

Install

npm install --global wasmpp

Usage

wasmpp <file> [options]

Options

  -h --help            Show this information
  --version            Show version
  -o FILE, --out=FILE  Write output to FILE
  -r DIR, --root=DIR   Root directory for resolving absolute paths of includes
  -D <macro>=<value>   Define <macro> to <value> (or empty string if <value> omitted)
  --no-comments        Remove all comments
  --compress           Remove all unnecessary spaces

Example

wasmpp src/main.wat -o build/app.wat -D DEBUG && wat2wasm build/app.wat -o build/app.wasm

( * to create wasm file, you need to install wabt or analogues)

API

Install

npm install wasmpp

Usage

import { preprocessor } from "wasmpp";

const result = preprocessor({
  source: "(module)",        // {string} (optional) -  the source code (by default, it is read from a file)
  pathname: "src/main.wat",  // {string} - the path to the source file
  root: "src",               // {string} (optional) - the root directory for resolving the absolute paths to the inclusions
  macros: ["A 1", "B"],      // {string[]} (optional) - initial macros definitions "<identifier> ...<replacement>"
  comments: true,            // {boolean} (optional) - leave all comments (default true)
  spaces: true,              // {boolean} (optionsl) - leave all spaces (default true)
  directives: null           // {Object<string,function>} - custom extra directives
});

Preprocessor Directives

Macro definition

(#define <identifier> ...<replacement>)

(#define (identifier ...<parameters>) ...<replacement>)

There are two types of macros: object-like and function-like. Object-like macros do not take parameters; function-like macros do (although the list of parameters may be empty).

A macro definition can be removed with #undef:

(#undef <identifier>)

Whenever the identifier appears in the source code it is replaced with the replacement, which can be empty.

Object-like macros were conventionally used as part of good programming practice to create symbolic names for constants; for example:

(#define PI 3.14159)

instead of hard-coding numbers throughout the code.

An example of a function-like macro is:

(#define (CONST_32 x) i32.const x)

The expression (CONST_32 42) will be replaced by i32.const 42.

In combination with the #eval and other directives, you can create function-like macros with unlimited functionality.

(#define (RAD2DEG rad) (#eval rad * 180 / Math.PI ))

f64.const (RAD2DEG 1)
(#ifndef TOP (#define TOP 0))
(#define (SAVE value)
  (i32.store (i32.const TOP) (i32.const value))
  (#define TOP (#eval TOP + 4))
)

(SAVE 42)

And #eval also has access to the globalThis (or global) object where it can save variables and functions...

(#eval global.top = 0; "")
(#define (SAVE value)
  (i32.store (i32.const (#eval let a=top;top+=4;a)) (i32.const value))
)

Conditional compilation

(#ifdef <identifier> ...<statement>) - if defined

(#ifndef <identifier> ...<statement>) - if not defined

Checking the definition exists.

(#if (...<expression>) ...<statement>)

Checking the expression returns a truthy value. The expression can be any valid JavaScript expression.

(#defined <identifier>)

Replaced by 1 if the definition exists, otherwise by 0.

(#ifdef <identifier> ...) and (#if ((#defined <identifier>)) ...) is the same thing, as well (#ifndef <identifier> ...) and (#if (!(#defined <identifier>)) ...), but you can do something like this, for example: (#if ((#defined SOMETHING) && (#defined SOMETHING_ELSE)) ...)

Evaluate expresions

(#eval ...<expression>)

Evaluates JavaScript expresion and returns its completion value. It is indispensable if you need to calculate something. For example:

f64.const (#eval Math.PI * 2 * SOMETHING)

Including files

(#include <filepath>)

The preprocessor replaces the (#include <filepath>) with the textual content of the file. Before each inclusion, the file is processed by the preprocessor.

(#include data <filepath>)

Replaced with content of the file as a string. Specifically for the data section.

(#size <filepath>)

When you include a data file, you may need to know the size of the data. This directive is replaced by the size of the corresponding file.

License

MIT