From 89d25cf24d77e7c2ab87d430eca635b59f806b32 Mon Sep 17 00:00:00 2001 From: Syuparn Date: Sat, 20 Feb 2021 22:31:45 +0900 Subject: [PATCH 1/2] add quine example --- example/quine.tmpl | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 example/quine.tmpl diff --git a/example/quine.tmpl b/example/quine.tmpl new file mode 100644 index 0000000..2dd1d3c --- /dev/null +++ b/example/quine.tmpl @@ -0,0 +1,3 @@ +{{- $code := `{{- $code := @ -}} +{{- $code | replace (printf "%c" 64) (print "\u0060" $code "\u0060") | println -}}` -}} +{{- $code | replace (printf "%c" 64) (print "\u0060" $code "\u0060") | println -}} From 2ae53bf3c9c5ffa8889998c1de26bedb793dd8b3 Mon Sep 17 00:00:00 2001 From: Syuparn Date: Sun, 21 Feb 2021 11:54:57 +0900 Subject: [PATCH 2/2] add examples --- example/bf_interpreter.tmpl | 168 +++++++++++++++++++++++++++++++++ example/control_functions.tmpl | 7 ++ example/janken.tmpl | 25 +++++ example/quine_incremental.tmpl | 5 + 4 files changed, 205 insertions(+) create mode 100644 example/bf_interpreter.tmpl create mode 100644 example/janken.tmpl create mode 100644 example/quine_incremental.tmpl diff --git a/example/bf_interpreter.tmpl b/example/bf_interpreter.tmpl new file mode 100644 index 0000000..433c5eb --- /dev/null +++ b/example/bf_interpreter.tmpl @@ -0,0 +1,168 @@ +{{- define "_bf" -}} + {{- if ge .tokPos (len .src) -}} + {{- /* parse ends. do nothing more */ -}} + {{- else -}} + {{- template "_bfParse" $ -}} + {{- end -}} +{{- end -}} + +{{- define "_bfParse" -}} + {{- $tok := index .src .tokPos -}} + {{- if eq $tok '+' -}} + {{- template "_bfPlus" $ -}} + {{- template "_bf" $ -}} + {{- else if eq $tok '-' -}} + {{- template "_bfMinus" $ -}} + {{- template "_bf" $ -}} + {{- else if eq $tok '>' -}} + {{- template "_bfInc" $ -}} + {{- template "_bf" $ -}} + {{- else if eq $tok '<' -}} + {{- template "_bfDec" $ -}} + {{- template "_bf" $ -}} + {{- else if eq $tok ',' -}} + {{- template "_bfGet" $ -}} + {{- template "_bf" $ -}} + {{- else if eq $tok '.' -}} + {{- template "_bfPut" $ -}} + {{- template "_bf" $ -}} + {{- else if eq $tok '[' -}} + {{- template "_bfWhile" $ -}} + {{- template "_bf" $ -}} + {{- else if eq $tok ']' -}} + {{- template "_bfEnd" $ -}} + {{- template "_bf" $ -}} + {{- else -}} + {{- /* do nothing and parse next token */ -}} + {{- $_ := set $ "tokPos" (add1 .tokPos) -}} + {{- template "_bf" $ -}} + {{- end -}} +{{- end -}} + +{{- define "_bfPlus" -}} + {{- $_ := set .mem (toString .ptr) (mod (add1 (get .mem (toString .ptr))) 256) -}} + {{- $_ = set $ "tokPos" (add1 .tokPos) -}} +{{- end -}} + +{{- define "_bfMinus" -}} + {{- /* NOTE: mod cannot be used because mod of minus value is minus! */ -}} + {{- $v := sub (get .mem (toString .ptr)) 1 -}} + {{- $_ := set .mem (toString .ptr) ((ge $v 0) | ternary $v (add $v 256)) -}} + {{- $_ = set $ "tokPos" (add1 .tokPos) -}} +{{- end -}} + +{{- define "_bfInc" -}} + {{- $_ := set $ "ptr" (add1 .ptr) -}} + {{- $_ = set $ "tokPos" (add1 .tokPos) -}} +{{- end -}} + +{{- define "_bfDec" -}} + {{- $_ := set $ "ptr" (sub .ptr 1) -}} + {{- $_ = set $ "tokPos" (add1 .tokPos) -}} +{{- end -}} + +{{- define "_bfGet" -}} + {{- $got := (ge (len .in) 0) | ternary (index .in 0) "" -}} + {{- $_ := set .mem (toString .ptr) $got -}} + {{- $_ = set $ "in" (.in | substr 1 (len .in)) -}} + {{- $_ = set $ "tokPos" (add1 .tokPos) -}} +{{- end -}} + +{{- define "_bfPut" -}} + {{- printf "%c" (index .mem (toString .ptr)) -}} + {{- $_ := set $ "tokPos" (add1 .tokPos) -}} +{{- end -}} + +{{- define "_bfWhile" -}} + {{- if (index .mem (toString .ptr)) -}} + {{- $_ := set $ "tokPos" (add1 .tokPos) -}} + {{- else -}} + {{- /* preceed position to corresponding "]" */ -}} + + {{- $nestCnt := 1 -}} + {{- /* token position to jump */ -}} + {{- $pos := 0 -}} + {{- range $i := untilStep (add1 .tokPos | int) (len .src) 1 -}} + {{- if eq (index $.src $i) '[' -}} + {{- $nestCnt = add1 $nestCnt -}} + {{- else if eq (index $.src $i) ']' -}} + {{- $nestCnt = sub $nestCnt 1 -}} + {{- end -}} + + {{- /* set position just after first corresponding "]" */ -}} + {{- if and (not $pos) (eq $nestCnt 0) -}} + {{- $pos = add1 $i -}} + {{- end -}} + {{- end -}} + + {{- $_ := set $ "tokPos" (default $pos (len .src)) -}} + {{- end -}} +{{- end -}} + +{{- define "_bfEnd" -}} + {{- if not (index .mem (toString .ptr)) -}} + {{- $_ := set $ "tokPos" (add1 .tokPos) -}} + {{- else -}} + {{- /* get position back to corresponding "[" */ -}} + + {{- $nestCnt := 1 -}} + {{- /* token position to jump */ -}} + {{- $pos := -1 -}} + {{- range $i := untilStep (sub .tokPos 1 | int) -1 -1 -}} + {{- if eq (index $.src $i) ']' -}} + {{- $nestCnt = add1 $nestCnt -}} + {{- else if eq (index $.src $i) '[' -}} + {{- $nestCnt = sub $nestCnt 1 -}} + {{- end -}} + + {{- /* set position just after the last corresponding "[" */ -}} + {{- if and (eq $pos -1) (eq $nestCnt 0) -}} + {{- $pos = add1 $i -}} + {{- end -}} + {{- end -}} + + {{- $_ := set $ "tokPos" $pos -}} + {{- end -}} +{{- end -}} + +{{- /* only for debugging */ -}} +{{- define "_bfDump" -}} + {{- println "in: " .in -}} + {{- println "src: " .src -}} + {{- println "ptr: " .ptr -}} + {{- println "tokPos: " .tokPos -}} + {{- range $i := until (len .mem) -}} + {{- printf "%3d " (index $.mem (toString $i)) -}} + {{- if eq (mod $i 16) 15 -}} + {{- println -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- define "bf" -}} + {{- $src := index $ 0 -}} + {{- $in := index $ 1 -}} + + {{- /* initialize memory */ -}} + {{- $MemSize := 1024 -}} + {{- $mem := dict -}} + {{- range $i := until $MemSize -}} + {{- /* HACK: assign to dummy var to be evaluated as "" */ -}} + {{- /* HACK: use dict instead of list to access address in O(1) */ -}} + {{- $_ := set $mem (toString $i) 0 -}} + {{- end -}} + + {{- /* initialize pointer address */ -}} + {{- $ptr := 0 -}} + + {{- /* initialize parsing position */ -}} + {{- $tokPos := 0 -}} + + {{- template "_bf" dict "src" $src "in" $in "mem" $mem "ptr" $ptr "tokPos" $tokPos -}} +{{- end -}} + +{{- /* give source code and stdin */ -}} +{{- template "bf" list ` + +++++++++[>++++++++>+++++++++++>+++>+<<<<-]>.>++.+++++++..+++. + >+++++.<<+++++++++++++++.>.+++.------.--------.>+.>+. +` "" -}} diff --git a/example/control_functions.tmpl b/example/control_functions.tmpl index b2f09d3..f59ff92 100644 --- a/example/control_functions.tmpl +++ b/example/control_functions.tmpl @@ -9,5 +9,12 @@ {{- default "no value found" $dict.c | println}} {{- default "no value found" $dict.c | println}} +{{- /* search elements in nested map without nil pointer dereference: dig */ -}} +{{- $d := dict "foo" (dict "bar" (dict "hoge" 1))}} +{{- /* 1 */ -}} +{{- dig "foo" "bar" "hoge" "not found..." $d | println}} +{{- /* "not found..." */ -}} +{{- dig "foo" "piyo" "hoge" "not found..." $d | println}} + {{- /* raise exception: fail */ -}} {{- /* fail "exception raised!" */ -}} diff --git a/example/janken.tmpl b/example/janken.tmpl new file mode 100644 index 0000000..97bf056 --- /dev/null +++ b/example/janken.tmpl @@ -0,0 +1,25 @@ +{{- /* Janken (Rock-Paper-Scissors) game */ -}} +{{- /* input your hand to stdin! */ -}} + +{{- /* gu, rock: ✊ */ -}} +{{- /* choki, scissors: ✌ */ -}} +{{- /* pa, paper: 🖐 */ -}} + +{{- /* constants */ -}} +{{- $HandDict := dict "gu" 0 "choki" 1 "pa" 2 "rock" 0 "scissors" 1 "paper" 2 -}} +{{- $HandIcons := list "✊" "✌" "🖐" -}} + +{{- if not (keys $HandDict | has .) -}} + {{- fail (printf "%s cannot be used as a hand!" .) -}} +{{- end -}} + +{{- $playerHand := index $HandDict .}} +{{- $comHand := randInt 0 3 -}} + +{{- /* show result */ -}} +{{- println "You\t\tChallenger" -}} +{{- printf "%s\tVS\t%s\n" (index $HandIcons $playerHand) (index $HandIcons $comHand)}} + +{{- $result := mod (add (sub $playerHand $comHand) 3) 3 -}} +{{- $resultStrs := list "Draw." "You lost..." "You won!" -}} +{{- printf "\n%s\n" (index $resultStrs $result) -}} diff --git a/example/quine_incremental.tmpl b/example/quine_incremental.tmpl new file mode 100644 index 0000000..a33661e --- /dev/null +++ b/example/quine_incremental.tmpl @@ -0,0 +1,5 @@ +{{- $n := 1 -}} +{{- $code := `{{- $n := ${n} -}} +{{- $code := @ -}} +{{- $code | replace (print "${" "n" "}") (add1 $n | toString) | replace (printf "%c" 64) (print "\u0060" $code "\u0060") | println -}}` -}} +{{- $code | replace (print "${" "n" "}") (add1 $n | toString) | replace (printf "%c" 64) (print "\u0060" $code "\u0060") | println -}}