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

m3k

v0.1.9

Published

m3k is a lisp dialect that compiles to JavaScript

Downloads

13

Readme

m3k

npm version

m3k is a Lisp dialect that compiles to JavaScript. This repository contains the source code of the compiler. Project is still work in progress.

try: https://obsfx.github.io/m3k/

Usage

Installation

npm i -g m3k

Usage

m3k input.lisp

or

Installation

npm i m3k

Usage

import m3k from 'm3k'

const tokens = m3k.tokenize(source)
const ast = m3k.parse(tokens)
const transformAST = m3k.transform(ast)
const code = m3k.generate(transformAST)

or

<script src="m3k.js"></script>
<script>
  const tokens = m3k.tokenize(source)
  const ast = m3k.parse(tokens)
  const transformAST = m3k.transform(ast)
  const code = m3k.generate(transformAST)
</script>

Language Overview

;; Variables and data types                                 compiled output
(define variable-name value)
(define x 5)                                                ;; let x = 5;
(define pet "Dog")                                          ;; let pet = "Dog";
(define negative-ten (- 10))                                ;; let negativeTen = -10;
(define number-list (list 1 2 3 4 5))                       ;; let numberList = [1, 2, 3, 4, 5];
(define third-el-list (nth 2 (list 1 2 3 4 5)))             ;; let thirdElList = [1, 2, 3, 4, 5][2];
(define dict-example (dict :name "Joe" :surname "Dow"))     ;; let dictExample = {name: "Joe", surname: "Dow"};
(define dict-example-name (getval name dict-example))       ;; let dictExampleName = dictExample.name;

;; Function definition
(define add (defun (a b) (+ a b)))                          ;; let add = (a, b) => (a + b);
(define add-and-print (defun (a b)                          ;; let addAndPrint = (a, b) => ((() => {
    (progn                                                  ;;  console.log(a + b);
        (print (+ a b))                                     ;;  return a + b;
        (+ a b))))                                          ;; })());

;; Reassigning variables
(set! variable-name value)
(set! r 15)                                                 ;; r = 15;

;; Pre-defined Methods
(print "hello world")                                       ;; console.log("hello world");
(append arr1 (list 1 2 3 "list-data") arr2)                 ;; [...arr1, ...[1, 2, 3, "list-data"], ...arr2];
(shift arr)                                                 ;; arr.shift();
(unshift arr 1)                                             ;; arr.unshift(1);
(pop arr)                                                   ;; arr.pop();
(push arr 1)                                                ;; arr.push(1);
(includes arr "thing")                                      ;; arr.includes("thing");
(concat arr1 arr2)                                          ;; arr1.concat(arr2);
(join arr ", ")                                             ;; arr.join(", ");
(slice "test-str" 1)                                        ;; "test-str".slice(1);
(splice arr 5 1)                                            ;; arr.splice(5, 1);
(map arr (defun (element index) (* 2 element)))             ;; arr.map((element, index) => (2 * element));
(for-each arr (defun (element index)                        ;; arr.forEach((element, index) => (
                  (print element index)))                   ;; 			console.log(element, index)));
(filter arr (defun (element index) (< element index)))      ;; arr.filter((element, index) => (element < index));
(find arr (defun (element index) (< element index)))        ;; arr.find((element, index) => (element < index));
(reduce arr (defun (prev current) (+ prev current)) 0)      ;; arr.reduce((prev, current) => (prev + current), 0);

;; Accessing JavaScript objects
(getval property object)
(getval body document)                                      ;; document.body
(define canvas ((getval create-element document) "canvas")) ;; let canvas = document.createElement("canvas");

;; Comparison
(!= 5 5)                                                    ;; 5 !== 5;
(= 5 5)                                                     ;; 5 === 5;
(>= 5 5)                                                    ;; 5 >= 5;
(<= 5 5)                                                    ;; 5 <= 5;
(% 5 5)                                                     ;; 5 % 5;

;; Conditional
(if (= 4 5)                                                 ;; (() => {
    (print "equal")                                         ;; if (4 === 5) { return console.log("equal");}
    (print "not equal"))                                    ;; else { return console.log("not equal");}})();

References

  • (How to Write a (Lisp) Interpreter (in Python)): https://norvig.com/lispy.html
  • the-super-tiny-compiler: https://github.com/jamiebuilds/the-super-tiny-compiler
  • Visitor: https://refactoring.guru/design-patterns/visitor
  • Crafting Interpreters: https://craftinginterpreters.com

TODO

  • [x] primitive types
  • [x] variables
  • [x] list
  • [x] dict
  • [x] methods
  • [x] accessing objects
  • [ ] loops
  • [x] functions
  • [x] if statements
  • [ ] comment lines
  • [ ] return expression
  • [ ] error for reserved keywords
  • [ ] canvas utils
  • [ ] built-in draw methods
  • [ ] 3D transformations utils
  • [ ] keyboards input utils
  • [ ] documentation