[obsidian] vault backup: 2023-11-25 02:30:30[

This commit is contained in:
松浦 知也 Matsuura Tomoya 2023-11-25 02:30:30 +09:00
parent 8542666642
commit 3e2aa4cfa4
2 changed files with 18 additions and 31 deletions

View File

@ -8,23 +8,9 @@
(let double (lambda (x) (* x x)) (double 6)) (let double (lambda (x) (* x x)) (double 6))
``` ```
まあプリミティブ演算は四則演算だけで再帰関数は自力で定義 ただ再帰は今のところ難しい。多分ListとAtomの区別がきちんとできてないせいで不動点コンビネータがきちんと動かない。
```lisp
(let fix あくまで雰囲気重視で、ということなのだが、結果的にコードが短いため初学者にわかりやすいかと言われると、かなりコメントを足していかないと読めなさそう。
(lambda (f)
(
(lambda (x) (f (lambda(y) (x x y))))
(lambda (x) (f (lambda(y) (x x y))))
)
)
(let fact
(fix (lambda (f) (lambda (n) (if n (* n (f (- n 1))) 1) ) ))
(fact 10)
)
)
%% 一行に直す %%
(let fix (lambda (f) ( (lambda (x) (f (lambda(y) (x x y)))) (lambda (x) (f (lambda(y) (x x y))))))(let fact (fix (lambda (f) (lambda (n) (if n (* n (f (- n 1))) 1) ) ))(fact 10)))
```
```js ```js
const reader = require("readline").createInterface({ const reader = require("readline").createInterface({
@ -65,11 +51,7 @@ const parse = (tokens) => {
} }
return next_res return next_res
} }
const read = (str) => parse(tokenize(str));
const read = (str) => {
const res = parse(tokenize(str));
return res
}
const binop = (args, fn) => fn(args[0], args[1]); const binop = (args, fn) => fn(args[0], args[1]);
@ -78,7 +60,8 @@ const env = {
"+": args => binop(args, (a, b) => a + b), "+": args => binop(args, (a, b) => a + b),
"-": args => binop(args, (a, b) => a - b), "-": args => binop(args, (a, b) => a - b),
"*": args => binop(args, (a, b) => a * b), "*": args => binop(args, (a, b) => a * b),
"/": args => binop(args, (a, b) => a / b) "/": args => binop(args, (a, b) => a / b),
"if": args => args[0] ? args[1] : args[2]
} }
const try_find = (name, env) => { const try_find = (name, env) => {
@ -92,30 +75,34 @@ const try_find = (name, env) => {
} }
} }
const eval = (expr, env) => { const eval = (expr, env) => {
if (expr ==null){
return null;
}
if (!Array.isArray(expr)) { if (!Array.isArray(expr)) {
return !isNaN(parseFloat(expr)) ? parseFloat(expr) : try_find(expr, env) return !isNaN(parseFloat(expr)) ? parseFloat(expr) : try_find(expr, env)
} else { } else {
const op = expr.shift(); const op = expr.shift();
switch (op) { switch (op) {
case 'let': { case 'let': {
let res = eval(expr[1], env);
let newenv = { "parent": env }; let newenv = { "parent": env };
env[expr[0]] = eval(expr[1], newenv); newenv[expr[0]] = res;
return eval(expr[2], env) return eval(expr[2], newenv)
} }
case 'lambda': return ['closure', expr[0], expr[1], env]//ids,body,env case 'lambda': return ['closure', expr[0], expr[1], env]//ids,body,env
default: { default: {
let fn = try_find(op, env); let fn = eval(op, env);
if (fn) { if (fn) {
if (Array.isArray(fn) && fn[0] === "closure") { if (Array.isArray(fn) && fn[0] === "closure") {//closure
for (let i = 0; i < fn[1].length; i++) { for (let i = 0; i < fn[1].length; i++) {
fn[3][fn[1][i]] = expr[i] fn[3][fn[1][i]] = eval(expr[i],env)
} }
return eval(fn[2], fn[3]) return eval(fn[2], fn[3])
} else { } else {//extern function
return fn(expr.map(e => eval(e, env))) return fn(expr.map(e => eval(e, env)))
} }
} else { } else {
console.error(`symbol ${op} not found`) return fn
} }
} }
} }

View File

@ -1,6 +1,6 @@
#programming-language #compiler-design #programming-language #compiler-design
[[Node.jsで100行で書くLISP風ラムダ計算]] [[Node.jsで100行で書くLISP風ラムダ計算]]
[Write a JavaScript Parser in Rust](https://oxc-project.github.io/javascript-parser-in-rust/ja/docs/intro/) [Write a JavaScript Parser in Rust](https://oxc-project.github.io/javascript-parser-in-rust/ja/docs/intro/)