上記インタプリタ用ソース
上記インタプリタは以下のコードでテストをしています。
このコードをtest.nscmという名前で保存し、
cscript scheme.js test.nscm
と入力すれば、実行できます。
コメントを多めに入れてあるので、この言語のチュートリアル的な使い方も出来るかもです。
################ ### コメント ### ################ #これはコメントです #this is comment #################### ### 基本データ型 ### #################### # 文字列 "this is #string" #正の整数(リテラルでは整数しか表現できない) 1 #負の整数(リテラルでは整数しか表現できない) (- 0 1) # 真値(true) T #偽値(NULL もしくは false) NIL ############ ### 変数 ### ############ # 変数の宣言 # int x = 1; (define x 1) #変数への代入 # x = x+1; (update x (+ x 1)) ################# ### 四則演算 ### ################# # 四則演算 (+ 1 2) (- 1 2) (* 1 2) (/ 1 2) # 複合した演算 # (1+2) * (3-4) / 5 (/ (* (+ 1 2) (- 3 4)) 5) ############ ### 比較 ### ############ # ==, != (eq 1 2) (ne 1 2) # <, <= (lt 1 2) (le 1 2) # >, >= (gt 1 2) (ge 1 2) ################ ### 論理演算 ### ################ # not (not T) # &&, || (and T NIL) (or T NIL) ############ ### 構文 ### ############ # 分岐(if) # if(x==1) puts("x is 1"); # else puts("x is not 1"); (if (eq x 1) (p "x is 1") (p "x is not 1")) # 分岐(switch) # switch(x){ # case 1: "one"; break; # case 2: "two"; break; # default: "other";break; # } (case x (1 "one") (2 "two") "other") # デフォルトの場合、恐ろしいバグがあります。 # 分岐(連続if else) # if(x==1) puts("x is 1"); # else if(x==2) puts("x is not 1"); # else puts("other"); (cond ( ((eq x 1) (p "one")) ((eq x 2) (p "two")) (T (p "other")))) # ループ # int i=0; # while(i<10){ # printf("%d\n", i); # i = i + 1; # } (define i 0) (while (le i 10) (p i) (update i (+ i 1))) # 順列動作 # puts("1"); # puts("2"); (begin (p "1") (p "2")) # 一時変数 # { # int w=1,x=2,y=3,z=4; # (w+x)*y/z; # } (let ((w 1)(x 2)(y 3)(z 4)) (/ (* (+ w x) y) z)) ############## ### 入出力 ### ############## # 入力から一文字取得し、その文字コードを返す # getc(); (getc) # 引数の文字コードがあらわす文字を出力 # putc(100); (putc 100) # オブジェクトを適切な表現で出力 # printf(???); (p 12) (p "hello") (p (cons 1 "abc")) (p (list 1 2 3 4 5)) (p (lambda (x) (+ x 1))) #################### ### データ型変換 ### #################### # toString((char)100) (conv 100) # toInteger('c') (conv "d") # "abc".getCharCodeAt(0) => '97' (car "abc") (car "") # => NIL # "abc".substring(1,2) => "bc" (cdr "abc") (cdr "a") # => NIL (cdr "") # => NIL # "abc" + (char) 100; (+ "abc" 100) ############ ### 関数 ### ############ # 関数の宣言 # int fib(int n){ # if(n<2) return n; # else return fib(n-1) + fib(n-2); #} (define fib (lambda (n) (if (lt n 2) 1 (+ (fib (- n 1)) (fib (- n 2)))))) # 呼び出し # fib(5); (fib 5) #################### ### 複合データ型 ### #################### # 複合データ型 (cons 1 "one") # => (1 . "one") # 値の取り出し (define cell (cons 1 "one")) (car cell) # => 1 (cdr cell) # => "one" #ネストした複合データ型 (cons (cons 1 2) (cons 3 4)) #=> ((1 . 2) . (3 . 4)) #配列 #(list 1 2 3)と同じ (cons 1 (cons 2 (cons 3 NIL))) #=> (1 . (2 . (3 . NIL))) ############ ### 配列 ### ############ # 配列の宣言 # int nums[5] = {1,2,3,4,5}; (define nums (list 1 2 3 4 5)) # 配列の要素の参照 # nums[0], nums[1], nums[2], ... (car nums) (car (cdr nums)) (car (cdr (cdr nums))) # 配列要素の破壊的変更 (define foo (cons 97 98)) (setcar foo (conv (car foo))) (setcdr foo (conv (cdr foo))) foo #配列を順番に処理 # for(int i=0;i<5;i++) printf("%d\n", nums[i]); (define ptr nums) (while (eq ptr NIL) (p (car ptr)) (update ptr (cdr ptr))) ###################### ### 構造体・クラス ### ###################### # 構造体(のようなもの) # struct human {string name; int age;}; # humen h("kouichi", 25); (define human cons) (define name car) (define age cdr) (define k (human "kouichi" 25)) (name k) (age k) # クロージャによるカプセル化 (define NumAdder (lambda (x) (lambda (a) (update x (+ x a)) x))) (define adder1 (NumAdder 0)) (adder1 1) (adder1 3) (adder1 5) ################ ### 例外処理 ### ################ # try{ throw 1+2; } # catch(x){return x;} (catch (p (throw (+ 1 2)))) ############## ### マクロ ### ############## #引数をそのまま返す関数 (quote (1 2 3 4)) (quote if) # マクロ if文と逆の動きをする、if_notマクロ (define if_not (macro (cond fcase tcase) (list (quote if) cond tcase fcase))) (if_not (eq 1 2) "false" "true") #################### ### 配列操作関数 ### #################### (define ns (list 1 5 2 4 3)) # ソート (sort ns) # 配列の順序を逆にする (reverse ns) # 検索 (find ns (lambda (x) (eq (% x 2) 1))) # 全ての要素を二乗した配列を返す (map ns (lambda(x)(* x x))) # 全ての要素の合計を取り出す (reduce ns 0 +) ################################ ### インタプリタの実行時起動 ### ################################ # 構文解析 (parse "(+ 1 2)") # 構文解析された式を評価 (eval (car (parse "(+ 1 2)"))) # プログラムでプログラムを作成 (define program (list (quote lambda) (list (quote name)) (list (quote +) "hello " (quote name)))) # プログラムが作ったプログラムを評価 ((eval program) "xyz")