上記インタプリタ用ソース

上記インタプリタは以下のコードでテストをしています。

このコードを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")