{"id":13744509,"url":"https://github.com/rzubek/as_lisp","last_synced_at":"2026-03-15T20:47:08.960Z","repository":{"id":11756425,"uuid":"14288899","full_name":"rzubek/as_lisp","owner":"rzubek","description":"Lisp dialect written in Actionscript","archived":false,"fork":false,"pushed_at":"2013-11-25T00:02:42.000Z","size":196,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-30T01:28:59.162Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"ActionScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rzubek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-11-11T01:46:56.000Z","updated_at":"2020-12-12T12:25:34.000Z","dependencies_parsed_at":"2022-07-12T19:50:30.107Z","dependency_job_id":null,"html_url":"https://github.com/rzubek/as_lisp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rzubek/as_lisp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rzubek%2Fas_lisp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rzubek%2Fas_lisp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rzubek%2Fas_lisp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rzubek%2Fas_lisp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rzubek","download_url":"https://codeload.github.com/rzubek/as_lisp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rzubek%2Fas_lisp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30550865,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-15T15:03:43.933Z","status":"ssl_error","status_checked_at":"2026-03-15T15:03:37.630Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T05:01:10.898Z","updated_at":"2026-03-15T20:47:08.924Z","avatar_url":"https://github.com/rzubek.png","language":"ActionScript","funding_links":[],"categories":["Apps \u0026 Tools","Runtimes"],"sub_categories":["Interpreters"],"readme":"as_lisp\n=======\n\n**as_lisp** is a Lisp dialect implemented in Actionscript. \n\nIt's a bytecode compiled language, and comes with its own compiler and a small bytecode interpreter, both written in Actionscript. The language includes the typical Lisp-dialect features you'd expect, like proper closures, tail-call optimization, and macros. \n\nLanguage implementation should be pretty readable and easy to extend (which also means: it's not particularly optimized). Compiler and bytecode design are heavily influenced by (ie. cribbed from) Quinnec's *\"Lisp in Small Pieces\"* and Norvig's *\"Principles of Artificial Intelligence Programming\"* . Standing on the shoulders on giants. :)  \n\n**as_lisp** is intended to be used as a library, embedded in another host program, and not a standalone executable. The compiler, bytecode interpreter, and runtime environment, are all easy to access and manipulate from host programs. A simple REPL console host app is included as an example. Since **as_lisp** can run inside the Adobe Flash runtime, it's compatible with a wide range of environments, including web browsers, and standalone AIR apps (iOS, Android, PC/Mac).\n\nThis is very much a work in progress, so please pardon the dust, use at your own risk, and so on. :)\n\n\n\n### USAGE\n\n```actionscript\nvar ctx :Context = new Context(null, true); // make a new vm + compiler\nctx.execute(\"(+ 1 2)\");                     // =\u003e [ 3 ]\n```\n\n\n### LANGUAGE DETAILS\n\nValue types:\n-  Boolean - #t or #f, backed by Actionscript boolean\n-  Number - same as Actionscript Number (floating point double)\n-  String - same as Actionscript String (immutable char sequence in double quotes)\n-  Symbol - similar to Scheme\n-  Cons - pair of expressions\n-  Closure - non-inspectable pair of environment and compiled code sequence\n\nSmall set of reserved keywords - everything else is a valid symbol\n-  quote\n-  begin\n-  set!\n-  if\n-  if*\n-  lambda\n-  defmacro\n-  .\n\nTail calls get optimized during compilation, without any language hints\n```lisp\n  (define (rec x) (if (= x 0) 0 (rec (- x 1))))\n  (rec 1000000) ;; look ma, no stack overflow!\n```\n\nQuotes, quasiquotes and unquotes are supported in the Lisp fashion:\n```\n  'x                 ;; =\u003e 'x\n  `x                 ;; =\u003e 'x\n  `,x                ;; =\u003e x\n  `(1 ,(list 2 3))   ;; =\u003e '(1 (2 3))\n  `(1 ,@(list 2 3))  ;; =\u003e '(1 2 3)\n```\n\nClosures\n```lisp\n  (set! fn (let ((sum 0)) (lambda (delta) (set! sum (+ sum delta)) sum))) \n  (fn 0)    ;; =\u003e 0\n  (fn 100)  ;; =\u003e 100\n  (fn 0)    ;; =\u003e 100\n```\n\nMacros are more like Lisp than Scheme. \n```lisp\n  ;; (let ((x 1) (y 2)) (+ x 1)) =\u003e \n  ;;   ((lambda (x y) (+ x y)) 1 2)\n  (defmacro let (bindings . body) \n    `((lambda ,(map car bindings) ,@body) \n      ,@(map cadr bindings)))\n```\n\nMacroexpansion - single-step and full\n```lisp\n  (and 1 (or 2 3))         ;; =\u003e 2\n  (mx1 '(and 1 (or 2 3)))  ;; =\u003e (if 1 (core:or 2 3) #f)\n  (mx '(and 1 (or 2 3)))   ;; =\u003e (if 1 (if* 2 3) #f)\n```\n\nBuilt-in primitives live in the \"core\" package and can be redefined\n```lisp\n  (+ 1 2)               ;; =\u003e 3\n  (set! core:+ core:*)  ;; =\u003e [Closure]\n  (+ 1 2)               ;; =\u003e 2\n```\n\nPackages \n```lisp\n  (package-set \"math\")       ;; =\u003e \"math\"\n  (package-get)              ;; =\u003e \"math\"\n  (package-import (\"core\"))  ;; =\u003e null\n  (package-export '(sin cos))\n```\n\nBuilt-in primitives are very bare bones (for now):\n-  Functions:\n  -  + - * / = != \u003c \u003c= \u003e \u003e= \n  -  const list append length\n  -  not null? cons? atom? string? number? boolean?\n  -  car cdr cadr cddr caddr cdddr map\n  -  mx mx1 trace gensym\n  -  package-set package-get package-import package-export\n  -  first second third rest\n  -  fold-left fold-right\n-  Macros\n  -  let let* letrec define\n  -  and or cond case\n-  Flash interop\n  -  new deref ..\n\n\n\n##### TODOS\n\n- Fix bugs (hah!)\n- Build out the standard library\n- Flesh out Flash interop. Right now it's in its infancy:\n    - `(new '(flash geom Point) 2 3)                ;; =\u003e [Native: (x=2, y=3)]`\n    - `(deref (new '(flash geom Point) 2 3) 'x)     ;; =\u003e 2  `\n    - `  ;; also (.. instance '(field1 field2)) == (deref (deref instance field1) field2)`\n- Peephole optimizer. Also optimize execution of built-in primitives.\n- Add better debugging: trace function calls, their args and return values, etc\n\n\n##### KNOWN BUGS\n\n- Error messages are somewhere between opaque and completely misleading\n- Redefining a known macro as a function will fail silently in weird ways\n- Symbol / package resolution is buggy - eg. if a symbol \"foo\" is defined in core \n  but not in the package \"bar\", then \"bar:foo\" will resolve to \"core:foo\" \n  even though it should resolve as undefined.\n\n\n\n#####  COMPILATION EXAMPLES\n\n```\ninputs:  (+ 1 2)\nparsed:  (core:+ 1 2)\n  ARGS  0\n  CONST 1\n  CONST 2\n  GVAR  core:+\n  CALLJ 2\n\ninputs:  (begin (+ (+ 1 2) 3) 4)\nparsed:  (begin (core:+ (core:+ 1 2) 3) 4)\n  ARGS  0\n  SAVE  \"K0\"  11\n  SAVE  \"K1\"  7\n  CONST 1\n  CONST 2\n  GVAR  core:+\n  CALLJ 2\nLABEL \"K1\"\n  CONST 3\n  GVAR  core:+\n  CALLJ 2\nLABEL \"K0\"\n  POP\n  CONST 4\n  RETURN\n\ninputs:  ((lambda (a) a) 5)\nparsed:  ((lambda (a) a) 5)\n  ARGS  0\n  CONST 5\n  FN  [Closure] ; (a)\n    ARGS  1\n    LVAR  0 0 ; a\n    RETURN\n  CALLJ 1\n\ninputs:  (begin (set! incf (lambda (x) (+ x 1))) (incf (incf 5)))\nparsed:  (begin (set! foo:incf (lambda (foo:x) (core:+ foo:x 1))) (foo:incf (foo:incf 5)))\n  ARGS  0\n  FN  [Closure] ; ((core:+ foo:x 1))\n    ARGS  1\n    LVAR  0 0 ; foo:x\n    CONST 1\n    GVAR  core:+\n    CALLJ 2\n  GSET  foo:incf\n  POP\n  SAVE  \"K0\"  8\n  CONST 5\n  GVAR  foo:incf\n  CALLJ 1\nLABEL \"K0\"\n  GVAR  foo:incf\n  CALLJ 1\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frzubek%2Fas_lisp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frzubek%2Fas_lisp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frzubek%2Fas_lisp/lists"}