nendo 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/nendo CHANGED
@@ -1,12 +1,47 @@
1
1
  #!/usr/local/bin/ruby -W0
2
+ # -*- encoding: utf-8 -*-
2
3
  #
3
- # Nendo: "Principle of Least Surprise (for Rubyist)"
4
+ # Nendo: "Nendo is a diarect of Lisp."
4
5
  #
5
6
  require 'nendo'
7
+ require 'getoptlong'
6
8
 
7
9
  def main
10
+ loadInit = true
8
11
  core = Nendo.new()
9
- core.loadInitFile
12
+
13
+ opts = GetoptLong.new(
14
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
15
+ [ '--no-init-file', '-q', GetoptLong::NO_ARGUMENT ],
16
+ [ '--load', '-l', GetoptLong::REQUIRED_ARGUMENT ]
17
+ ).each { |opt, arg|
18
+ case opt
19
+ when '--help'
20
+ puts <<-EOF
21
+
22
+ nendo [OPTION] [script-file]
23
+
24
+ -h, --help:
25
+ show help
26
+
27
+ -q, --no-init-file:
28
+ Does not read the default initialization file.
29
+
30
+ -l, --load:
31
+ Does not read the default initialization file.
32
+
33
+ EOF
34
+ when '--no-init-file'
35
+ loadInit = false
36
+ when '--load'
37
+ core.load( arg )
38
+ STDERR.printf( "loaded file [%s]\n", arg )
39
+ end
40
+ }
41
+
42
+ if loadInit
43
+ core.loadInitFile
44
+ end
10
45
  if 0 < ARGV.length
11
46
  core.load( ARGV[0] )
12
47
  else
@@ -0,0 +1,100 @@
1
+ #!/bin/sh
2
+ :; #-*- mode: nendo; syntax: scheme -*-;;
3
+ :; exec /usr/local/bin/nendo $0 $*
4
+
5
+ (load-library "text/html-lite")
6
+ (load-library "text/tree")
7
+ (require "cgi")
8
+ (require "RMagick")
9
+
10
+ (define (response-dekamoji str pointsize)
11
+ (let* ((font-dots pointsize)
12
+ (margin (* pointsize 0.3))
13
+ (image (Magick::Image.new (+ (* str.size font-dots) margin) (+ font-dots margin)))
14
+ (imlist (Magick::ImageList.new))
15
+ (dr (Magick::Draw.new)))
16
+ (set! image.background_color "none")
17
+ (set! image.format "PNG")
18
+ (imlist.push image)
19
+ ;;(set! dr.font "/Volumes/Macintosh HD/Library/Fonts/ホリデイMDJP03")
20
+ ;;(set! dr.font "/Volumes/Macintosh HD/Library/Fonts/みかちゃん")
21
+ ;;(set! dr.font "/Volumes/Macintosh HD/Library/Fonts/ヒラギノ丸ゴ ProN W4.otf")
22
+ ;;(set! dr.font "/Volumes/Macintosh HD/Library/Fonts/ヒラギノ明朝 Pro W6.otf")
23
+ (set! dr.font "/Volumes/Macintosh HD/Library/Fonts/ヒラギノ明朝 Pro W3.otf")
24
+ (set! dr.pointsize pointsize)
25
+ (set! dr.fill "#404040")
26
+ (set! dr.stroke "#080808")
27
+ (set! dr.font_weight Magick::BoldWeight)
28
+ (set! dr.gravity Magick::CenterGravity)
29
+ (dr.annotate imlist 0 0 0 0 str)
30
+ (let1 blur (imlist.blur_image 1.0 1.0)
31
+ (blur.to_blob))))
32
+
33
+
34
+ (define default-wording "デカ文字")
35
+ (define default-size 2)
36
+ (define size-list '(
37
+ (1 . "サイズ小")
38
+ (2 . "サイズ中")
39
+ (3 . "サイズ大")
40
+ (4 . "サイズ特大")
41
+ ))
42
+
43
+
44
+ (define (top-page params)
45
+ (let* ((size (if (hash-table-exist? params "size")
46
+ (to-i (car (to-list (hash-table-get params "size"))))
47
+ default-size))
48
+ (wording (if (hash-table-exist? params "w")
49
+ (car (to-list (hash-table-get params "w")))
50
+ default-wording)))
51
+ (let* ((size (if (> 1 size) 1 size))
52
+ (size (if (< (length size-list) size) (length size-list) size)))
53
+ `(
54
+ ,(html-doctype)
55
+ ,(html:head
56
+ (html:title "デカ文字作成"))
57
+ ,(html:body
58
+ (html:div :style "text-align: center; "
59
+ (html:h1 "デカ文字作成")
60
+ (html:p
61
+ "下記に文章を入れて『画像化』ボタンを押して下さい")
62
+ (html:form
63
+ :method "GET"
64
+ :action "./dekamoji.cgi"
65
+ (html:input :name "w" :type "text" :cols 140 :value wording)
66
+ (map
67
+ (lambda (x)
68
+ (list
69
+ (html:input :name "size" :type "radio"
70
+ :value (car x)
71
+ :CHECKED (eq? (car x) size))
72
+ (cdr x)))
73
+ size-list)
74
+ (html:br)
75
+ (html:input :type "submit" :value "画像化"))
76
+ (html:hr)
77
+ (html:img :src (sprintf "./dekamoji.cgi?img=1&size=%d&w=%s" size wording))
78
+ (html:hr)))))))
79
+
80
+ (define fontsize-alist '(
81
+ ("1" . 40)
82
+ ("2" . 80)
83
+ ("3" . 160)
84
+ ("4" . 260)
85
+ ))
86
+
87
+ (let1 cgi (CGI.new)
88
+ (cond ((hash-table-exist? cgi.params "img")
89
+ (cgi.print
90
+ (cgi.header "image/png"))
91
+ (cgi.print
92
+ (response-dekamoji
93
+ (car (to-list (hash-table-get cgi.params "w")))
94
+ (assv-ref (car (to-list (hash-table-get cgi.params "size"))) fontsize-alist))))
95
+ (else
96
+ (cgi.print
97
+ (cgi.header))
98
+ (cgi.print
99
+ (tree->string
100
+ (top-page cgi.params))))))
@@ -0,0 +1,32 @@
1
+ #!/bin/sh
2
+ :; #-*- mode: nendo; syntax: scheme -*-;;
3
+ :; exec /usr/local/bin/nendo $0 $*
4
+
5
+ (load-library "text/html-lite")
6
+ (load-library "text/tree")
7
+ (require "cgi")
8
+
9
+ (define (params-list-page cgi)
10
+ `(
11
+ ,(html-doctype)
12
+ ,(html:head
13
+ (html:title "CGI parameter list"))
14
+ ,(html:body
15
+ (html:h1 "CGI parameter list")
16
+ (html:table :border 1
17
+ (html:tr
18
+ (html:th "key")
19
+ (html:th "value"))
20
+ (hash-table-for-each cgi.params
21
+ (lambda (key value)
22
+ (html:tr
23
+ (html:td key)
24
+ (html:td (string-join value.to_list "/")))))))))
25
+
26
+
27
+ (let1 cgi (CGI.new)
28
+ (cgi.print
29
+ (cgi.header))
30
+ (cgi.print
31
+ (tree->string
32
+ (params-list-page cgi))))
File without changes
@@ -1,6 +1,6 @@
1
1
  #!/bin/sh
2
- true; #-*- mode: nendo; syntax: scheme -*-;;
3
- true; exec /usr/local/bin/nendo $0 $*
2
+ :; #-*- mode: nendo; syntax: scheme -*-;;
3
+ :; exec /usr/local/bin/nendo $0 $*
4
4
 
5
5
  ;; fact
6
6
  (define (fact n)
@@ -1,6 +1,6 @@
1
1
  #!/bin/sh
2
- true; #-*- mode: nendo; syntax: scheme -*-;;
3
- true; exec /usr/local/bin/nendo $0 $*
2
+ :; #-*- mode: nendo; syntax: scheme -*-;;
3
+ :; exec /usr/local/bin/nendo $0 $*
4
4
 
5
5
  ;; FizzBuzz write in Nendo
6
6
  (define (fizzbuzz max)
@@ -0,0 +1,51 @@
1
+ #!/bin/sh
2
+ :; #-*- mode: nendo; syntax: scheme -*-;;
3
+ :; exec /usr/local/bin/nendo $0 $*
4
+
5
+ (load-library "text/html-lite")
6
+ (load-library "text/tree")
7
+
8
+ (define (page-sample)
9
+ `(
10
+ ,(html:head
11
+ (html:title "title of page"))
12
+ ,(html:body
13
+ (html:p "これはサンプルです")
14
+ (html:h1 "section 1")
15
+ (html:h2 "section 1-2")
16
+ (html:table :border 1
17
+ (html:tr
18
+ (html:th "head1")
19
+ (html:th "head2"))
20
+ (html:tr
21
+ (html:td "data1")
22
+ (html:td "data2"))
23
+ (html:tr
24
+ (html:td "data3")
25
+ (html:td "data4"))
26
+ (html:hr)))))
27
+
28
+ (write-tree
29
+ (page-sample))
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
@@ -4,8 +4,4 @@
4
4
  (enable-idebug)
5
5
  (define debug-print-length 256)
6
6
 
7
- "abc"
8
- "a\nb"
9
- "a\"b"
10
- "abc\"abc\""
11
- "abc\'abc\'"
7
+
File without changes
data/lib/init.nnd CHANGED
@@ -107,6 +107,8 @@
107
107
  (define (ninth lst) (nth 8 lst))
108
108
  (define (tenth lst) (nth 9 lst))
109
109
 
110
+ (define (x->string object) (to-s object))
111
+
110
112
  ;; ----------------------------------------
111
113
  ;; basic forms
112
114
  ;; ----------------------------------------
@@ -126,7 +128,9 @@
126
128
  (let ((condition (if (eq? 'else (car elem))
127
129
  true
128
130
  (car elem)))
129
- (body (cdr elem))
131
+ (body (if (null? (cdr elem))
132
+ '(#t)
133
+ (cdr elem)))
130
134
  (tmpsym (gensym)))
131
135
  ;;(display "CONDITION") (print condition)
132
136
  ;;(display "BODY") (print body)
@@ -311,6 +315,13 @@
311
315
  ;; don't touch
312
316
  `(let ,@lst))))
313
317
 
318
+ ;; ----------------------------------------
319
+ ;; errorf
320
+ ;; ----------------------------------------
321
+ (define errorf
322
+ (macro (format . args)
323
+ `(error
324
+ (sprintf ,format ,@args))))
314
325
 
315
326
  ;; ----------------------------------------
316
327
  ;; List utilities imported from TinyScheme
@@ -388,6 +399,13 @@
388
399
  (filter-map pred (cdr lst))))))
389
400
 
390
401
 
402
+ (define (find pred lst)
403
+ (let1 result (filter pred lst)
404
+ (if (null? result)
405
+ #f
406
+ (car result))))
407
+
408
+
391
409
  (define lambda
392
410
  (macro src
393
411
  (if (not (list? (cadr src)))
@@ -477,43 +495,80 @@
477
495
  (let*-expand exps body))))
478
496
 
479
497
 
498
+ ;; ----------------------------------------
499
+ ;; values
500
+ ;; ----------------------------------------
501
+ (define (values . args)
502
+ (case (length args)
503
+ ((1)
504
+ (car args))
505
+ (else
506
+ (make-values args))))
507
+
508
+
509
+ (define (call-with-values producer consumer)
510
+ (let ((v (producer)))
511
+ (if (values? v)
512
+ (apply consumer (values-values v))
513
+ (consumer v))))
514
+
515
+ ;; srfi-8
516
+ (define receive
517
+ (macro (vars expr . body)
518
+ `(call-with-values
519
+ (lambda () ,expr)
520
+ (lambda ,vars ,@body))))
521
+
522
+
523
+ ;; ----------------------------------------
524
+ ;; keyword
525
+ ;; ----------------------------------------
526
+ (define (get-keyword key kv-list . fallback)
527
+ (cond
528
+ ((or (not (list? kv-list)) (>= 2 (length kv-list)))
529
+ (if (null? fallback)
530
+ (errorf "Error: imcomplete key list: %s\n" (write-to-string kv-list))
531
+ (car fallback)))
532
+ (else
533
+ (let loop ((k (car kv-list))
534
+ (v (cadr kv-list))
535
+ (rest (cddr kv-list)))
536
+ (if (eq? k key)
537
+ v
538
+ (case (length rest)
539
+ ((0)
540
+ (if (null? fallback)
541
+ (errorf "Error: value for key %s is not provided : %s\n" (write-to-string key) (write-to-string kv-list))
542
+ (car fallback)))
543
+ ((1)
544
+ (errorf "Error: incomplete key list: %s\n" (write-to-string kv-list)))
545
+ (else
546
+ (loop (car rest)
547
+ (cadr rest)
548
+ (cddr rest)))))))))
549
+
480
550
  ;; ----------------------------------------
481
551
  ;; for Ruby interop
482
552
  ;; ----------------------------------------
483
- ;; dot_operator
484
553
  (define dot-operator
485
554
  (macro lst
486
- (letrec ((dot-operator-iter
555
+ (letrec ((generate-method-call-form
487
556
  (lambda (lst)
488
- (cond
489
- ((null? lst)
490
- '())
491
- ((pair? lst)
492
- (if (eq? 'dot-operator (car lst))
493
- (intern
494
- (string-join
495
- (map
496
- (lambda (x)
497
- (if (pair? x)
498
- (to-s (dot-operator-iter x))
499
- (if (symbol? x)
500
- (to-s x)
501
- (error (sprintf "dot-operator requires symbol, but got %s" x)))))
502
- (cdr lst))
503
- "."))
504
- (error "dot-operator requires symbol or (. symbol symbol) form.")))
505
- (else
506
- lst)))))
507
-
557
+ (let1 tmp (gensym)
558
+ (if (symbol? (first lst))
559
+ `(,(string->symbol (+ (to-s (first lst)) "." (to-s (second lst))))
560
+ ,@(cddr lst))
561
+ `(let ((,tmp ,(first lst)))
562
+ (,(string->symbol (+ (to-s tmp) "." (to-s (second lst))))
563
+ ,@(cddr lst))))))))
508
564
  (cond
509
- ((eq? 0 (length lst))
510
- (error ". operator requires argument"))
511
- ((and (eq? 1 (length lst))
512
- (symbol? (car lst)))
513
- (intern (+ "." (to-s (car lst)))))
565
+ ((> 2 (length lst))
566
+ (raise ArgumentError ". dot-operator requires 2+ arguments."))
514
567
  (else
515
- ((dot-operator-iter
516
- (cons 'dot-operator lst))))))))
568
+ (if (symbol? (second lst))
569
+ (generate-method-call-form lst)
570
+ (raise TypeError ". dot-operator requires method name as symbol.")))))))
571
+
517
572
 
518
573
  (define (with-open filename pred . lst)
519
574
  (let1 len (length lst)
@@ -538,6 +593,92 @@
538
593
  x))
539
594
 
540
595
 
596
+ (define (cons* arg . args)
597
+ (if (null? args)
598
+ arg
599
+ (cons arg (apply list* args))))
600
+ (define list* cons*)
601
+
602
+
603
+ ;; ----------------------------------------
604
+ ;; hash-table library functions
605
+ ;; ----------------------------------------
606
+ (define (make-hash-table)
607
+ (Hash.new))
608
+
609
+ (define (hash-table? h)
610
+ (h.is_a? Hash))
611
+
612
+ (define (hash-table-num-entries h)
613
+ (h.length))
614
+
615
+ (define (hash-table . kv-list)
616
+ (let1 h (make-hash-table)
617
+ (for-each
618
+ (lambda (entry)
619
+ (if (pair? (cdr entry))
620
+ (hash-table-put! h (car entry) (cadr entry))
621
+ (hash-table-put! h (car entry) (cdr entry))))
622
+ kv-list)
623
+ h))
624
+
625
+ (define (hash-table-exist? h key)
626
+ (h.has_key? key))
627
+
628
+ (define (hash-table-clear! h)
629
+ (h.clear))
630
+
631
+ (define (hash-table-delete! h key)
632
+ (h.delete key))
633
+
634
+ (define (hash-table-keys h)
635
+ (to-list (h.keys)))
636
+
637
+ (define (hash-table-values h)
638
+ (to-list (h.values)))
639
+
640
+ (define (hash-table-map h pred)
641
+ (let1 keys (hash-table-keys h)
642
+ (map
643
+ (lambda (key)
644
+ (pred key (hash-table-get h key)))
645
+ keys)))
646
+ (define hash-table-for-each hash-table-map)
647
+
648
+ (define (hash-table->alist h)
649
+ (if (not (h.is_a? Hash))
650
+ (raise TypeError "Error: hash-table->alist expects Hash instance.")
651
+ (let1 keys (hash-table-keys h)
652
+ (map
653
+ (lambda (key)
654
+ (cons key (hash-table-get h key)))
655
+ keys))))
656
+
657
+ (define (alist->hash-table alist)
658
+ (if (not (list? alist))
659
+ (raise TypeError "Error: alist->hash-table expects alist.")
660
+ (apply hash-table alist)))
661
+
662
+ ;; ----------------------------------------
663
+ ;; Ruby interop librarys
664
+ ;; ----------------------------------------
665
+ ;; I will implement in the future...
666
+ (define export
667
+ (macro (name)
668
+ `(define ,name nil)))
669
+
670
+ (define (load-library name)
671
+ (let* ((home (get-nendo-home))
672
+ (path (+ home "/" name)))
673
+ (cond
674
+ ((File.exist? (+ path ".nndc"))
675
+ (load-compiled-code (+ path ".nndc")))
676
+ ((File.exist? (+ path ".nnd"))
677
+ (load (+ path ".nnd")))
678
+ (else
679
+ (errorf "Error: can't load library file [%s]\n" path )))))
680
+
681
+
541
682
  ;; ----------------------------------------
542
683
  ;; Utility function for testing and debugging
543
684
  ;; ----------------------------------------