From 95bfa95b5d901a08cc8327f39742f3937009e227 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Sat, 7 Jul 2018 11:56:25 -0700 Subject: [PATCH] demo langs for Racket School --- .../atomic-taco-demo/main.rkt | 14 +++ .../atomic-taco-demo/test.rkt | 4 + .../javascriptlike-demo/expander.rkt | 59 ++++++++++ .../javascriptlike-demo/grammar.rkt | 23 ++++ .../javascriptlike-demo/info.rkt | 3 + .../javascriptlike-demo/less-rackety.rkt | 102 ++++++++++++++++++ .../javascriptlike-demo/main.rkt | 33 ++++++ .../javascriptlike-demo/rackety.rkt | 64 +++++++++++ .../javascriptlike-demo/sexped.rkt | 30 ++++++ .../javascriptlike-demo/test.rkt | 32 ++++++ .../passthrough-demo/main.rkt | 5 + .../passthrough-demo/test.rkt | 4 + .../pl-checklist-demo/main.rkt | 1 + .../pl-checklist-demo/test.rkt | 1 + .../pl-checklist-lang-maker/checklist.txt | 8 ++ .../pl-checklist-lang-maker/main.rkt | 63 +++++++++++ .../pythonesque-demo/grammar.rkt | 19 ++++ .../pythonesque-demo/main.rkt | 96 +++++++++++++++++ .../pythonesque-demo/test.rkt | 51 +++++++++ .../quantum-taco-demo/main.rkt | 20 ++++ .../quantum-taco-demo/test.rkt | 4 + .../regexcellent-demo/grammar.rkt | 16 +++ .../regexcellent-demo/main.rkt | 66 ++++++++++++ .../regexcellent-demo/test.rkt | 11 ++ .../simplex-demo/grammar.rkt | 8 ++ beautiful-racket-demo/simplex-demo/main.rkt | 35 ++++++ beautiful-racket-demo/simplex-demo/test.rkt | 4 + .../taco-compiler-demo/main.rkt | 23 ++++ .../taco-compiler-demo/test.rkt | 4 + .../taco-decompiler-demo/main.rkt | 23 ++++ .../taco-decompiler-demo/run.rkt | 27 +++++ .../taco-decompiler-demo/test.rkt | 34 ++++++ .../taco-victory-demo/grammar.rkt | 5 + .../taco-victory-demo/main.rkt | 31 ++++++ .../taco-victory-demo/test.rkt | 2 + .../tacogram-demo/grammar.rkt | 7 ++ beautiful-racket-demo/tacogram-demo/main.rkt | 24 +++++ beautiful-racket-demo/tacogram-demo/test.rkt | 2 + .../tacopocalypse-demo/main.rkt | 33 ++++++ .../tacopocalypse-demo/test.rkt | 2 + .../tacopocalypse-prep/main.rkt | 23 ++++ .../tacopocalypse-prep/test.rkt | 34 ++++++ beautiful-racket-demo/xmlish-demo/grammar.rkt | 19 ++++ beautiful-racket-demo/xmlish-demo/main.rkt | 46 ++++++++ beautiful-racket-demo/xmlish-demo/test.rkt | 10 ++ 45 files changed, 1125 insertions(+) create mode 100644 beautiful-racket-demo/atomic-taco-demo/main.rkt create mode 100644 beautiful-racket-demo/atomic-taco-demo/test.rkt create mode 100644 beautiful-racket-demo/javascriptlike-demo/expander.rkt create mode 100644 beautiful-racket-demo/javascriptlike-demo/grammar.rkt create mode 100644 beautiful-racket-demo/javascriptlike-demo/info.rkt create mode 100644 beautiful-racket-demo/javascriptlike-demo/less-rackety.rkt create mode 100644 beautiful-racket-demo/javascriptlike-demo/main.rkt create mode 100644 beautiful-racket-demo/javascriptlike-demo/rackety.rkt create mode 100644 beautiful-racket-demo/javascriptlike-demo/sexped.rkt create mode 100644 beautiful-racket-demo/javascriptlike-demo/test.rkt create mode 100644 beautiful-racket-demo/passthrough-demo/main.rkt create mode 100644 beautiful-racket-demo/passthrough-demo/test.rkt create mode 100644 beautiful-racket-demo/pl-checklist-demo/main.rkt create mode 100644 beautiful-racket-demo/pl-checklist-demo/test.rkt create mode 100644 beautiful-racket-demo/pl-checklist-lang-maker/checklist.txt create mode 100644 beautiful-racket-demo/pl-checklist-lang-maker/main.rkt create mode 100644 beautiful-racket-demo/pythonesque-demo/grammar.rkt create mode 100644 beautiful-racket-demo/pythonesque-demo/main.rkt create mode 100644 beautiful-racket-demo/pythonesque-demo/test.rkt create mode 100644 beautiful-racket-demo/quantum-taco-demo/main.rkt create mode 100644 beautiful-racket-demo/quantum-taco-demo/test.rkt create mode 100644 beautiful-racket-demo/regexcellent-demo/grammar.rkt create mode 100644 beautiful-racket-demo/regexcellent-demo/main.rkt create mode 100644 beautiful-racket-demo/regexcellent-demo/test.rkt create mode 100644 beautiful-racket-demo/simplex-demo/grammar.rkt create mode 100644 beautiful-racket-demo/simplex-demo/main.rkt create mode 100644 beautiful-racket-demo/simplex-demo/test.rkt create mode 100644 beautiful-racket-demo/taco-compiler-demo/main.rkt create mode 100644 beautiful-racket-demo/taco-compiler-demo/test.rkt create mode 100644 beautiful-racket-demo/taco-decompiler-demo/main.rkt create mode 100644 beautiful-racket-demo/taco-decompiler-demo/run.rkt create mode 100644 beautiful-racket-demo/taco-decompiler-demo/test.rkt create mode 100644 beautiful-racket-demo/taco-victory-demo/grammar.rkt create mode 100644 beautiful-racket-demo/taco-victory-demo/main.rkt create mode 100644 beautiful-racket-demo/taco-victory-demo/test.rkt create mode 100644 beautiful-racket-demo/tacogram-demo/grammar.rkt create mode 100644 beautiful-racket-demo/tacogram-demo/main.rkt create mode 100644 beautiful-racket-demo/tacogram-demo/test.rkt create mode 100644 beautiful-racket-demo/tacopocalypse-demo/main.rkt create mode 100644 beautiful-racket-demo/tacopocalypse-demo/test.rkt create mode 100644 beautiful-racket-demo/tacopocalypse-prep/main.rkt create mode 100644 beautiful-racket-demo/tacopocalypse-prep/test.rkt create mode 100644 beautiful-racket-demo/xmlish-demo/grammar.rkt create mode 100644 beautiful-racket-demo/xmlish-demo/main.rkt create mode 100644 beautiful-racket-demo/xmlish-demo/test.rkt diff --git a/beautiful-racket-demo/atomic-taco-demo/main.rkt b/beautiful-racket-demo/atomic-taco-demo/main.rkt new file mode 100644 index 0000000..8269866 --- /dev/null +++ b/beautiful-racket-demo/atomic-taco-demo/main.rkt @@ -0,0 +1,14 @@ +#lang racket +(provide #%datum #%top-interaction #%module-begin + (rename-out [#%my-app #%app])) + +(define-syntax (#%datum stx) + (syntax-case stx () + [(_ . THING) #''taco])) + +(define-syntax (#%my-app stx) + (syntax-case stx () + [(_ FUNC . ARGS) #'(list (#%datum) . ARGS)])) + +(module reader syntax/module-reader + atomic-taco-demo) \ No newline at end of file diff --git a/beautiful-racket-demo/atomic-taco-demo/test.rkt b/beautiful-racket-demo/atomic-taco-demo/test.rkt new file mode 100644 index 0000000..329eeec --- /dev/null +++ b/beautiful-racket-demo/atomic-taco-demo/test.rkt @@ -0,0 +1,4 @@ +#lang atomic-taco-demo + +"hello world" +(+ 1 (* 2 (- 3))) \ No newline at end of file diff --git a/beautiful-racket-demo/javascriptlike-demo/expander.rkt b/beautiful-racket-demo/javascriptlike-demo/expander.rkt new file mode 100644 index 0000000..b75cc7c --- /dev/null +++ b/beautiful-racket-demo/javascriptlike-demo/expander.rkt @@ -0,0 +1,59 @@ +#lang br/quicklang +(require racket/stxparam) +(provide (all-defined-out) (all-from-out br/quicklang)) + +(define-macro top #'begin) + +(define-macro (assignment ID VAL) #'(define ID VAL)) + +(define (add/concat . xs) + (cond + [(andmap number? xs) (apply + xs)] + [(ormap string? xs) (string-join (map ~a xs) "")])) + +(define-macro-cases sumlike + [(_ VAL) #'VAL] + [(_ . VALS) #'(add/concat . VALS)]) + +(define-macro (object (K V) ...) + #'(make-hash (list (cons K V) ...))) + +(define-macro (func-def (ARG ...) STMT ...) + #'(λ (ARG ...) + (let/cc return-cc + (syntax-parameterize ([return (make-rename-transformer #'return-cc)]) + STMT ... (void))))) + +(define-syntax-parameter return + (λ (stx) (error 'not-parameterized))) + +(define-macro (dotted-id (BASE KEY ...)) + #'(for/fold ([val BASE]) + ([key (in-list (list 'KEY ...))]) + (cond + [(hash-ref val key #f)] + [(hash-ref val (symbol->string key) #f)] + [else (error 'dotted-failure)]))) + +(define-macro func-app #'#%app) + +(define-macro (if COND . STMTS) + #'(when COND . STMTS)) + +(define-macro-cases comparison + [(_ VAL) #'VAL] + [(_ L == R) #'(equal? L R)] + [(_ L != R) #'(not (equal? L R))]) + +(define-macro (while COND STMT ...) + #'(let loop () + (when COND + STMT ... + (loop)))) + +(define alert displayln) + +(define-macro (increment ID) + #'(let () + (set! ID (add1 ID)) + ID)) \ No newline at end of file diff --git a/beautiful-racket-demo/javascriptlike-demo/grammar.rkt b/beautiful-racket-demo/javascriptlike-demo/grammar.rkt new file mode 100644 index 0000000..1f37164 --- /dev/null +++ b/beautiful-racket-demo/javascriptlike-demo/grammar.rkt @@ -0,0 +1,23 @@ +#lang brag + +top : @statement* +statement : (assignment | expr | return) /";" | if | while +assignment : /"var" id /"=" expr +@expr : comparison +comparison : [comparison ("!=" | "==")] sumlike +sumlike : [@sumlike /"+"] value +@value : id | INTEGER | STRING | object | func-def | func-app | increment +increment : id /"++" +object : /"{" @kvs /"}" +kvs : [kv (/"," kv)*] +/kv : expr /":" expr +func-def : /"function" /"(" ids /")" @block +/ids : [id (/"," id)*] +@id : ID | dotted-id +dotted-id : DOTTED-ID +block : /"{" @statement* /"}" +return : /"return" expr +func-app : id /"(" @exprs /")" +exprs : [expr (/"," expr)*] +if : /"if" /"(" expr /")" @block +while : /"while" /"(" expr /")" @block \ No newline at end of file diff --git a/beautiful-racket-demo/javascriptlike-demo/info.rkt b/beautiful-racket-demo/javascriptlike-demo/info.rkt new file mode 100644 index 0000000..2e9db11 --- /dev/null +++ b/beautiful-racket-demo/javascriptlike-demo/info.rkt @@ -0,0 +1,3 @@ +#lang info + +(define compile-omit-paths '("less-rackety.rkt")) \ No newline at end of file diff --git a/beautiful-racket-demo/javascriptlike-demo/less-rackety.rkt b/beautiful-racket-demo/javascriptlike-demo/less-rackety.rkt new file mode 100644 index 0000000..ff5f80c --- /dev/null +++ b/beautiful-racket-demo/javascriptlike-demo/less-rackety.rkt @@ -0,0 +1,102 @@ +#lang s-exp scriptlike +;; +;;var x = 42; +;(define x 42) + +(var x 42) + +;;var s = "string"; +;(define s "string") + +(var s "string") + +;; +;;x + x; +;(define (add/concat . xs) +; (cond +; [(andmap number? xs) (apply + xs)] +; [(ormap string? xs) (string-join (map ~a xs) "")])) +;(add/concat x x) + +(sumlike x x) + +;;s + x; +;(add/concat s x) + +(sumlike s x) + + +;; +;;var thing = { +;; 'foo' : 42, +;; +;; 'bar' : function(x) { +;; return x + 15; +;; } +;;}; + +; +;(define thing (hash +; "foo" 42 +; "bar" (λ (x) (let/ec return (return (add/concat x 15)) (void))))) +; + + +(object thing ("foo" 42) ("bar" (func (x) (return (sumlike x 15))))) + +;;thing.foo +;;thing.bar +;;thing.bar(3) + +; +;(hash-ref thing "foo") +;(hash-ref thing "bar") +;(#%app (hash-ref thing "bar") 3) + + +(dot thing "foo") +(dot thing "bar") +(func-app (dot thing "bar") 3) + +; +;; +;;if ( thing.foo == 42 ) { +;; console.log("The correct answer is " + thing.foo); +;;} +; +;(when (equal? (hash-ref thing "foo") 42) +; (displayln (add/concat "The correct answer is " (hash-ref thing "foo")))) + + +(object console ("log" (func (str) (pretty-print str)))) + +(if (comparison (dot thing "foo") "==" 42) + (func-app (dot console "log") (sumlike "The correct answer is " (dot thing "foo")))) + +; +;;var idx = 0; +;;while ( idx != 50 ) { +;; if ( thing.bar(idx) == 35 ) { +;; alert("Calamity at " + idx + "!"); +;; } +;; idx++; +;;} +; +;(define (alert str) +; (displayln "*********") +; (displayln str) +; (displayln "*********")) +; +;(define idx 0) +;(let loop () +; (when (not (equal? idx 50)) +; (when (equal? (#%app (hash-ref thing "bar") idx) 35) +; (alert (add/concat "Calamity at " idx "!"))) +; (set! idx (add1 idx)) +; (loop))) + +(var idx 0) +(while (comparison idx "!=" 50) + (if (comparison (func-app (dot thing "bar") idx) "==" 35) + (alert (sumlike "Calamity at " idx "!"))) + (increment idx)) \ No newline at end of file diff --git a/beautiful-racket-demo/javascriptlike-demo/main.rkt b/beautiful-racket-demo/javascriptlike-demo/main.rkt new file mode 100644 index 0000000..23f79e1 --- /dev/null +++ b/beautiful-racket-demo/javascriptlike-demo/main.rkt @@ -0,0 +1,33 @@ +#lang br/quicklang +(require "grammar.rkt" brag/support) + +(module+ reader + (provide read-syntax)) + +(define-lex-abbrev reserved-terms + (:or "var" "=" ";" "+" "{" "}" "'" "\"" + ":" "," "(" ")" "//" "/*" "*/" + "if" "while" "==" "!=" "function" "return" "++")) + +(define lex + (lexer + [(:or (from/stop-before "//" "\n") + (from/to "/*" "*/")) (token 'COMMENT #:skip? #t)] + [reserved-terms (token lexeme (string->symbol lexeme))] + [(:+ (:- (:or alphabetic punctuation) "." reserved-terms)) + (token 'ID (string->symbol lexeme))] + [(:+ (:- (:or alphabetic punctuation) reserved-terms)) + (token 'DOTTED-ID (map string->symbol (string-split lexeme ".")))] + [(:+ (char-set "0123456789")) + (token 'INTEGER (string->number lexeme))] + [(:or (from/to "\"" "\"") (from/to "'" "'")) + (token 'STRING (string-trim lexeme (substring lexeme 0 1)))] + [whitespace (token 'WHITE #:skip? #t)] + [any-char lexeme])) + +(define (read-syntax src ip) + (define parse-tree (parse (λ () (lex ip)))) + (strip-context + (with-syntax ([PT parse-tree]) + #'(module _ javascriptlike-demo/expander + PT)))) \ No newline at end of file diff --git a/beautiful-racket-demo/javascriptlike-demo/rackety.rkt b/beautiful-racket-demo/javascriptlike-demo/rackety.rkt new file mode 100644 index 0000000..4a0ae72 --- /dev/null +++ b/beautiful-racket-demo/javascriptlike-demo/rackety.rkt @@ -0,0 +1,64 @@ +#lang br +; +;var x = 42; +(define x 42) +;var s = "string"; +(define s "string") +; +;x + x; +(define (add/concat . xs) + (cond + [(andmap number? xs) (apply + xs)] + [(ormap string? xs) (string-join (map ~a xs) "")])) +(add/concat x x) +;s + x; +(add/concat s x) +; +;var thing = { +; 'foo' : 42, +; +; 'bar' : function(x) { +; return x + 15; +; } +;}; + +(define thing (hash + "foo" 42 + "bar" (λ (x) (let/ec return (return (add/concat x 15)) (void))))) + +;thing.foo +;thing.bar +;thing.bar(3) + +(hash-ref thing "foo") +(hash-ref thing "bar") +(#%app (hash-ref thing "bar") 3) + +; +;if ( thing.foo == 42 ) { +; console.log("The correct answer is " + thing.foo); +;} + +(when (equal? (hash-ref thing "foo") 42) + (displayln (add/concat "The correct answer is " (hash-ref thing "foo")))) + +;var idx = 0; +;while ( idx != 50 ) { +; if ( thing.bar(idx) == 35 ) { +; alert("Calamity at " + idx + "!"); +; } +; idx++; +;} + +(define (alert str) + (displayln "*********") + (displayln str) + (displayln "*********")) + +(define idx 0) +(let loop () + (when (not (equal? idx 50)) + (when (equal? (#%app (hash-ref thing "bar") idx) 35) + (alert (add/concat "Calamity at " idx "!"))) + (set! idx (add1 idx)) + (loop))) \ No newline at end of file diff --git a/beautiful-racket-demo/javascriptlike-demo/sexped.rkt b/beautiful-racket-demo/javascriptlike-demo/sexped.rkt new file mode 100644 index 0000000..609a0a4 --- /dev/null +++ b/beautiful-racket-demo/javascriptlike-demo/sexped.rkt @@ -0,0 +1,30 @@ +#lang s-exp scriptlike/expander + +(assignment x 42) +(assignment s "string") + +(sumlike x x) +(sumlike s x) + +(assignment thing (object + ("foo" 42) + + ("bar" (func-def (x) + (return (sumlike x 15)))))) + + + +(dotted-id (thing foo)) +(dotted-id (thing bar)) +(func-app (dotted-id (thing bar)) 3) + +(assignment console (object ("log" (func-def (str) (displayln str))))) ; simulates global console (don't put in parse tree) +(if (comparison (dotted-id (thing foo)) == 42) + (func-app (dotted-id (console log)) (sumlike "The correct answer is " (dotted-id (thing foo))))) + + +(assignment idx 0) +(while (comparison idx != 50) + (if (comparison (func-app (dotted-id (thing bar)) idx) == 35) + (alert (sumlike "Calamity at " idx "!"))) + (increment idx)) \ No newline at end of file diff --git a/beautiful-racket-demo/javascriptlike-demo/test.rkt b/beautiful-racket-demo/javascriptlike-demo/test.rkt new file mode 100644 index 0000000..25ed3de --- /dev/null +++ b/beautiful-racket-demo/javascriptlike-demo/test.rkt @@ -0,0 +1,32 @@ +#lang javascriptlike-demo + +var x = 42; +var s = "string"; + +x + x; // prints 84 +s + x; // prints "string42" + +var thing = { + "foo" : 42, + 'bar' : function(x) { + return x + 15; + } +}; + +thing.foo; // prints 42 +thing.bar; // prints # +thing.bar(3); // prints 18 + +if ( thing.foo == 42 ) { + // prints "The correct answer is 42" + alert("The correct answer is " + thing.foo); +} + +var idx = 0; +while ( idx != 50 ) { + if ( thing.bar(idx) == 35 ) { + // prints "Calamity at 20!" + alert("Calamity at " + idx + "!"); + } + idx++; +} diff --git a/beautiful-racket-demo/passthrough-demo/main.rkt b/beautiful-racket-demo/passthrough-demo/main.rkt new file mode 100644 index 0000000..3924eea --- /dev/null +++ b/beautiful-racket-demo/passthrough-demo/main.rkt @@ -0,0 +1,5 @@ +#lang racket +(provide (all-from-out racket)) + +(module reader syntax/module-reader + passthrough-demo) \ No newline at end of file diff --git a/beautiful-racket-demo/passthrough-demo/test.rkt b/beautiful-racket-demo/passthrough-demo/test.rkt new file mode 100644 index 0000000..63af9aa --- /dev/null +++ b/beautiful-racket-demo/passthrough-demo/test.rkt @@ -0,0 +1,4 @@ +#lang passthrough-demo + +"hello world" +(+ 1 (* 2 (- 3))) \ No newline at end of file diff --git a/beautiful-racket-demo/pl-checklist-demo/main.rkt b/beautiful-racket-demo/pl-checklist-demo/main.rkt new file mode 100644 index 0000000..364f35b --- /dev/null +++ b/beautiful-racket-demo/pl-checklist-demo/main.rkt @@ -0,0 +1 @@ +#lang pl-checklist-lang-maker \ No newline at end of file diff --git a/beautiful-racket-demo/pl-checklist-demo/test.rkt b/beautiful-racket-demo/pl-checklist-demo/test.rkt new file mode 100644 index 0000000..a7ae7f3 --- /dev/null +++ b/beautiful-racket-demo/pl-checklist-demo/test.rkt @@ -0,0 +1 @@ +#lang pl-checklist-demo \ No newline at end of file diff --git a/beautiful-racket-demo/pl-checklist-lang-maker/checklist.txt b/beautiful-racket-demo/pl-checklist-lang-maker/checklist.txt new file mode 100644 index 0000000..83a7947 --- /dev/null +++ b/beautiful-racket-demo/pl-checklist-lang-maker/checklist.txt @@ -0,0 +1,8 @@ +What kind of programming language do you propose to make? + +( ) concurrent ( ) declarative ( ) imperative ( ) functional +( ) asynchronous ( ) typed ( ) untyped ( ) semi-typed ( ) non-terminating +( ) lazy ( ) deterministic ( ) literate ( ) illiterate +( ) Forth-like ( ) Algol-inspired ( ) BASIC-infused ( ) Lispy +( ) modular ( ) multiprocess ( ) scalable ( ) unreasonable +( ) cloud-based ( ) ARM-compatible ( ) RISC-optimized \ No newline at end of file diff --git a/beautiful-racket-demo/pl-checklist-lang-maker/main.rkt b/beautiful-racket-demo/pl-checklist-lang-maker/main.rkt new file mode 100644 index 0000000..a25ca25 --- /dev/null +++ b/beautiful-racket-demo/pl-checklist-lang-maker/main.rkt @@ -0,0 +1,63 @@ +#lang at-exp br/quicklang +(require brag/support racket/runtime-path racket/file) + +(module reader syntax/module-reader + pl-checklist-lang-maker/main) + +(provide (rename-out [plc-mb #%module-begin])) + +(define-macro (plc-mb . ARGS) + #'(#%module-begin + (module+ main + (displayln "My new #lang technique is unstoppable")) + (module+ reader + (provide (rename-out [plc-rs read-syntax]))))) + + +(define (plc-rs path ip) + (strip-context + (with-syntax ([PT (parse (λ () (plc-lexer ip)))]) + #'(module _ (submod pl-checklist-lang-maker expander) + PT)))) + +(define plc-lexer + (lexer + [whitespace (token 'WHITE #:skip? #t)] + [(:: "(" (:? " ") ")") (token 'VALUE #f)] + [(:: "(" any-char ")") (token 'VALUE #t)] + [(:+ alphabetic punctuation) (token 'WORD lexeme)])) + + +@module/lang[parser]{ + #lang brag + + plc-top : (/WORD | plc-field)* + /plc-field : VALUE WORD +} + +(require 'parser) + +(module+ expander + (provide #%module-begin plc-top)) + +(define-runtime-path checklist "checklist.txt") + +(define-macro-cases plc-top + [(_) #'(displayln (string-append "\n" (file->string checklist)))] + [(_ (VAL NAME) ...) + #'(let ([adjectives (map cdr (filter car (list '(VAL . NAME) ...)))]) + (stringify adjectives))]) + +(define (stringify adjectives) + (displayln "") + (display + (if (pair? adjectives) + (string-append + "You appear to be proposing a new " + (string-join adjectives ", ") + " language. " + (if (< (length adjectives) 6) + "\n\nThat will never work." + "\n\nNow you're showing some ambition! Welcome to Racket School!")) + "No language proposed. You are in danger of flunking out."))) + diff --git a/beautiful-racket-demo/pythonesque-demo/grammar.rkt b/beautiful-racket-demo/pythonesque-demo/grammar.rkt new file mode 100644 index 0000000..f11efef --- /dev/null +++ b/beautiful-racket-demo/pythonesque-demo/grammar.rkt @@ -0,0 +1,19 @@ +#lang brag + +top : @statement* +statement : assignment | func-def | expr | return | for | if | print +assignment : ID /"=" expr +@expr : comparison +comparison : [comparison ("<" | ">")] sum +sum : [sum ("+" | "-")] product +product : [product ("*" | "/")] value +@value : ID | INTEGER | func-app | STRING +func-app : ID /"(" @exprs /")" +exprs : [expr (/"," expr)*] +func-def : /"def" ID /"(" ids /")" /":" @block +/ids : [ID (/"," ID)*] +block : /INDENT @statement* /DEDENT +return : /"return" expr +for : /"for" ID /"in" expr /":" @block +if : /"if" expr /":" block [/"else" /":" block] +print : /"print" expr \ No newline at end of file diff --git a/beautiful-racket-demo/pythonesque-demo/main.rkt b/beautiful-racket-demo/pythonesque-demo/main.rkt new file mode 100644 index 0000000..3fc4407 --- /dev/null +++ b/beautiful-racket-demo/pythonesque-demo/main.rkt @@ -0,0 +1,96 @@ +#lang br/quicklang +(require "grammar.rkt" brag/support racket/pretty racket/stxparam) +(provide (except-out (all-from-out br/quicklang) for if print) (all-defined-out) pretty-print) + +(module+ reader + (provide read-syntax)) + +(define-lex-abbrev reserved-terms + (:or "=" "def" "(" ")" ":" "," + "return" "for" "in" + "+" "-" "*" "/" "<" ">" "\"" + "if" "else" "print")) +(define-lex-abbrev indent (:: (:+ "\n") (:* " "))) + +(define prev-indent 0) +(define pending-dedents 0) + +(define (lex ip) + (define inner-lex + (lexer + [(eof) (cond + [(> prev-indent 0) + (set! pending-dedents prev-indent) + (set! prev-indent 0) + (lex input-port)] + [else eof])] + [(from/stop-before "#" "\n") (token 'COMMENT #:skip? #t)] + [indent + (match-let* ([(list _ spaces) (regexp-match #rx"^\n+( *)$" lexeme)] + [this-indent (/ (string-length spaces) 2)]) + (define tok + (cond + [(> (- this-indent prev-indent) 1) (error 'only-one-indent-please)] + [(> this-indent prev-indent) (token 'INDENT)] + [(< this-indent prev-indent) + (set! pending-dedents (- prev-indent this-indent)) + (lex input-port)] + [(= this-indent prev-indent) (token lexeme #:skip? #t)])) + (set! prev-indent this-indent) + tok)] + [(:+ whitespace) (token lexeme #:skip? #t)] + [reserved-terms (token lexeme (string->symbol lexeme))] + [(:+ (:- (:or alphabetic punctuation) reserved-terms)) + (token 'ID (string->symbol lexeme))] + [(:+ (char-set "0123456789")) + (token 'INTEGER (string->number lexeme))])) + (cond + [(equal? (peek-char ip) #\") (token 'STRING (read ip))] + [(> pending-dedents 0) + (set! pending-dedents (sub1 pending-dedents)) + (token 'DEDENT)] + [else (inner-lex ip)])) + +(define-macro top #'begin) +(define-macro (assignment ID EXPR) + #'(define ID EXPR)) + +(define-macro-cases comparison + [(_ ARG) #'ARG] + [(_ LARG OP RARG) #'(OP LARG RARG)]) + +(define-macro sum #'comparison) +(define-macro product #'comparison) + +(define-macro (func-def ID ID-ARGS STMT ...) + #'(define (ID . ID-ARGS) + (let/cc return-cc + (syntax-parameterize ([return (make-rename-transformer #'return-cc)]) + STMT ... (void))))) + +(define-syntax-parameter return (λ (stx) (error 'not-parameterized))) +(define-macro func-app #'#%app) + +(provide (rename-out [my-for for])) +(define-macro (my-for ID EXPR . STMTS) + #'(for ([ID (in-list EXPR)]) + . STMTS)) + +(define-macro block #'begin) + +(provide (rename-out [my-if if])) +(define-macro-cases my-if + [(_ COND TBLOCK) #'(when COND TRUE-BLOCK)] + [(_ COND TBLOCK FBLOCK) #'(if COND (let () TBLOCK) (let () FBLOCK))]) + +(provide (rename-out [my-print print])) +(define-macro (my-print EXPR) + #'(display EXPR)) + +(define (read-syntax src ip) + (define parse-tree (parse (λ () (lex ip)))) + (strip-context + (with-syntax ([PT parse-tree]) + #'(module _ pythonesque-demo + #;(pretty-print 'PT) + PT)))) \ No newline at end of file diff --git a/beautiful-racket-demo/pythonesque-demo/test.rkt b/beautiful-racket-demo/pythonesque-demo/test.rkt new file mode 100644 index 0000000..2b3c533 --- /dev/null +++ b/beautiful-racket-demo/pythonesque-demo/test.rkt @@ -0,0 +1,51 @@ +#lang pythonesque-demo + +a = 3 +b = 4 + +"middle \" escaped quote" +"ending escaped quote\"" +"middle \\ escaped backslash" +"ending escaped backslash\\" + +def ft(): + return 42 + +def gt(x, y): + return x > y + def noop(): + return "double dedent here" + + +def squaresum(x, y): + def add(c, d): + return c + d + return add(x, y) * add(x, y) + +gt(a, b) # #f +squaresum(b, a) # 49 + +println(a) + +expt(2, 4) + +range(1, 5) + +# keep indented example next to eof +for x in range(1, 5): + println(x * x) + +def foo(x): + x + +foo(42) # no return value + +if a < b: + print "a is less than b" +else: + print "a is not less than b" + +def bar(x, y): + return x > y + def noop(): + return "double dedent here" \ No newline at end of file diff --git a/beautiful-racket-demo/quantum-taco-demo/main.rkt b/beautiful-racket-demo/quantum-taco-demo/main.rkt new file mode 100644 index 0000000..1a35ed9 --- /dev/null +++ b/beautiful-racket-demo/quantum-taco-demo/main.rkt @@ -0,0 +1,20 @@ +#lang br/quicklang + +(module+ reader + (provide read-syntax)) + +(define (tokenize ip) + (for/list ([tok (in-port read ip)]) + tok)) + +(define (parse tok) + (if (list? tok) + (map parse tok) + 'taco)) + +(define (read-syntax src ip) + (define toks (tokenize ip)) + (define parse-tree (parse toks)) + (with-syntax ([(PT ...) parse-tree]) + #'(module tacofied racket + 'PT ...))) \ No newline at end of file diff --git a/beautiful-racket-demo/quantum-taco-demo/test.rkt b/beautiful-racket-demo/quantum-taco-demo/test.rkt new file mode 100644 index 0000000..1d8db75 --- /dev/null +++ b/beautiful-racket-demo/quantum-taco-demo/test.rkt @@ -0,0 +1,4 @@ +#lang quantum-taco-demo + +"hello world" +(+ 1 (* 2 (- 3))) \ No newline at end of file diff --git a/beautiful-racket-demo/regexcellent-demo/grammar.rkt b/beautiful-racket-demo/regexcellent-demo/grammar.rkt new file mode 100644 index 0000000..9dc3109 --- /dev/null +++ b/beautiful-racket-demo/regexcellent-demo/grammar.rkt @@ -0,0 +1,16 @@ +#lang brag + +top : (/NEWLINE+ [line])* /NEWLINE* +line : [lookbehind] pat [lookahead] +pat : repeat+ | choice +lookbehind : /"(" /"?" /"<" /"=" pat /")" +lookahead : /"(" /"?" /"=" pat /")" +choice : pat (/"|" pat)+ +repeat : repeatable [("*" | "+") ["?"] | "?"] +@repeatable : group | any | start | end | literals | chars +group : /"(" pat /")" +any : /"." +start : /"^" +end : /"$" +literals : LITERAL+ +chars : /"[" LITERAL* /"]" \ No newline at end of file diff --git a/beautiful-racket-demo/regexcellent-demo/main.rkt b/beautiful-racket-demo/regexcellent-demo/main.rkt new file mode 100644 index 0000000..df9a3dd --- /dev/null +++ b/beautiful-racket-demo/regexcellent-demo/main.rkt @@ -0,0 +1,66 @@ +#lang br/quicklang +(require brag/support "grammar.rkt") +(provide (all-from-out br/quicklang) (all-defined-out)) + +(module+ reader + (provide read-syntax)) + +(define-lex-abbrev regex-chars (char-set "()*+?.^$|symbol lexeme))] + [(:+ (char-set "0123456789")) (token 'INT (string->number lexeme))])) + +(define-macro top #'begin) + +(define-macro (func-def ID ARGIDS EXPR) + #'(define ID (λ ARGIDS EXPR))) + +(define-macro-cases expr + [(_ LEFT "+" RIGHT) #'(+ LEFT RIGHT)] + [(_ OTHER) #'OTHER]) + +(define-macro (func-app ID ARG ...) + #'(ID ARG ...)) + +(define (read-syntax src ip) + (define pt (parse (λ () (lex ip)))) + (strip-context + (with-syntax ([PT pt]) + #'(module mod-name simplex-demo + PT)))) \ No newline at end of file diff --git a/beautiful-racket-demo/simplex-demo/test.rkt b/beautiful-racket-demo/simplex-demo/test.rkt new file mode 100644 index 0000000..fda2067 --- /dev/null +++ b/beautiful-racket-demo/simplex-demo/test.rkt @@ -0,0 +1,4 @@ +#lang simplex-demo +fun f(x,y) = x + y +fun g(z) = f(z,z) +g(10) \ No newline at end of file diff --git a/beautiful-racket-demo/taco-compiler-demo/main.rkt b/beautiful-racket-demo/taco-compiler-demo/main.rkt new file mode 100644 index 0000000..b39d453 --- /dev/null +++ b/beautiful-racket-demo/taco-compiler-demo/main.rkt @@ -0,0 +1,23 @@ +#lang br/quicklang + +(module+ reader + (provide read-syntax)) + +(define (tokenize ip) + (for/list ([tok (in-port read-char ip)]) + tok)) + +(define (parse-char c) + (define int (modulo (char->integer c) 128)) + (for/list ([bit (in-range 7)]) + (if (bitwise-bit-set? int bit) + 'taco + null))) + +(define (read-syntax src ip) + (define toks (tokenize ip)) + (define parse-tree (map parse-char toks)) + (strip-context + (with-syntax ([(PARSED-CHAR ...) parse-tree]) + #'(module tacofied racket + (for-each displayln '(PARSED-CHAR ...)))))) \ No newline at end of file diff --git a/beautiful-racket-demo/taco-compiler-demo/test.rkt b/beautiful-racket-demo/taco-compiler-demo/test.rkt new file mode 100644 index 0000000..56d6bb6 --- /dev/null +++ b/beautiful-racket-demo/taco-compiler-demo/test.rkt @@ -0,0 +1,4 @@ +#lang taco-compiler-demo + +"hello world" +(+ 1 (* 2 (- 3))) \ No newline at end of file diff --git a/beautiful-racket-demo/taco-decompiler-demo/main.rkt b/beautiful-racket-demo/taco-decompiler-demo/main.rkt new file mode 100644 index 0000000..a126925 --- /dev/null +++ b/beautiful-racket-demo/taco-decompiler-demo/main.rkt @@ -0,0 +1,23 @@ +#lang br/quicklang + +(module+ reader + (provide read-syntax)) + +(define (tokenize ip) + (for/list ([tok (in-port read ip)]) + tok)) + +(define (parse tok) + (integer->char + (for/sum ([val (in-list tok)] + [power (in-naturals)] + #:when (eq? val 'taco)) + (expt 2 power)))) + +(define (read-syntax src ip) + (define toks (tokenize ip)) + (define parse-tree (map parse toks)) + (strip-context + (with-syntax ([PT parse-tree]) + #'(module untaco racket + (display (list->string 'PT)))))) \ No newline at end of file diff --git a/beautiful-racket-demo/taco-decompiler-demo/run.rkt b/beautiful-racket-demo/taco-decompiler-demo/run.rkt new file mode 100644 index 0000000..872ec93 --- /dev/null +++ b/beautiful-racket-demo/taco-decompiler-demo/run.rkt @@ -0,0 +1,27 @@ +#lang br/quicklang + +(module+ reader + (provide read-syntax)) + +(define (tokenize ip) + (for/list ([tok (in-port read ip)]) + tok)) + +(define (parse tok) + (integer->char + (for/sum ([val (in-list tok)] + [power (in-naturals)] + #:when (eq? val 'taco)) + (expt 2 power)))) + +(define (read-syntax src ip) + (define toks (tokenize ip)) + (define parse-tree (map parse toks)) + (define src-string (list->string parse-tree)) + (define racket-toks + (for/list ([tok (in-port read (open-input-string src-string))]) + tok)) + (strip-context + (with-syntax ([RACKET-TOKS racket-toks]) + #'(module untaco racket + . RACKET-TOKS)))) \ No newline at end of file diff --git a/beautiful-racket-demo/taco-decompiler-demo/test.rkt b/beautiful-racket-demo/taco-decompiler-demo/test.rkt new file mode 100644 index 0000000..82961e3 --- /dev/null +++ b/beautiful-racket-demo/taco-decompiler-demo/test.rkt @@ -0,0 +1,34 @@ +#lang taco-decompiler-demo +(() taco () taco () () ()) +(() taco () taco () () ()) +(() taco () () () taco ()) +(() () () taco () taco taco) +(taco () taco () () taco taco) +(() () taco taco () taco taco) +(() () taco taco () taco taco) +(taco taco taco taco () taco taco) +(() () () () () taco ()) +(taco taco taco () taco taco taco) +(taco taco taco taco () taco taco) +(() taco () () taco taco taco) +(() () taco taco () taco taco) +(() () taco () () taco taco) +(() taco () () () taco ()) +(() taco () taco () () ()) +(() () () taco () taco ()) +(taco taco () taco () taco ()) +(() () () () () taco ()) +(taco () () () taco taco ()) +(() () () () () taco ()) +(() () () taco () taco ()) +(() taco () taco () taco ()) +(() () () () () taco ()) +(() taco () () taco taco ()) +(() () () () () taco ()) +(() () () taco () taco ()) +(taco () taco taco () taco ()) +(() () () () () taco ()) +(taco taco () () taco taco ()) +(taco () () taco () taco ()) +(taco () () taco () taco ()) +(taco () () taco () taco ()) \ No newline at end of file diff --git a/beautiful-racket-demo/taco-victory-demo/grammar.rkt b/beautiful-racket-demo/taco-victory-demo/grammar.rkt new file mode 100644 index 0000000..8c5604d --- /dev/null +++ b/beautiful-racket-demo/taco-victory-demo/grammar.rkt @@ -0,0 +1,5 @@ +#lang brag +taco-program : taco-leaf* +taco-leaf : (taco | not-a-taco){7} +taco : /"%" +not-a-taco : /"#$" \ No newline at end of file diff --git a/beautiful-racket-demo/taco-victory-demo/main.rkt b/beautiful-racket-demo/taco-victory-demo/main.rkt new file mode 100644 index 0000000..8b2b605 --- /dev/null +++ b/beautiful-racket-demo/taco-victory-demo/main.rkt @@ -0,0 +1,31 @@ +#lang br/quicklang +(require brag/support "grammar.rkt") +(provide (all-from-out br/quicklang) (all-defined-out)) + +(module+ reader + (provide read-syntax)) + +(define lex + (lexer + ["#$" lexeme] + ["%" lexeme] + [any-char (lex input-port)])) + +(define (taco-program . pieces) pieces) + +(define (taco-leaf . pieces) + (integer->char + (for/sum ([bit (in-list pieces)] + [pow (in-naturals)]) + (* bit (expt 2 pow))))) + +(define (taco) 1) + +(define (not-a-taco) 0) + +(define (read-syntax src ip) + (define parse-tree (parse (λ () (lex ip)))) + (strip-context + (with-syntax ([PT parse-tree]) + #'(module vic taco-victory-demo + (display (apply string PT)))))) \ No newline at end of file diff --git a/beautiful-racket-demo/taco-victory-demo/test.rkt b/beautiful-racket-demo/taco-victory-demo/test.rkt new file mode 100644 index 0000000..a4d0443 --- /dev/null +++ b/beautiful-racket-demo/taco-victory-demo/test.rkt @@ -0,0 +1,2 @@ +#lang taco-victory-demo +##$%#$%#$#$#$$##$%#$%#$#$#$$##$%#$#$#$%#$$##$#$#$%#$%%$#%#$%#$#$%%$##$#$%%#$%%$##$#$%%#$%%$#%%%%#$%%$##$#$#$#$#$%#$$#%%%#$%%%$#%%%%#$%%$##$%#$#$%%%$##$#$%%#$%%$##$#$%#$#$%%$##$%#$#$#$%#$$##$%#$%#$#$#$$##$#$#$%#$%#$$#%%#$%#$%#$$##$#$#$#$#$%#$$#%#$#$#$%%#$$##$#$#$#$#$%#$$##$#$#$%#$%#$$##$%#$%#$%#$$##$#$#$#$#$%#$$##$%#$#$%%#$$##$#$#$#$#$%#$$##$#$#$%#$%#$$#%#$%%#$%#$$##$#$#$#$#$%#$$#%%#$#$%%#$$#%#$#$%#$%#$$#%#$#$%#$%#$$#%#$#$%#$%#$$ \ No newline at end of file diff --git a/beautiful-racket-demo/tacogram-demo/grammar.rkt b/beautiful-racket-demo/tacogram-demo/grammar.rkt new file mode 100644 index 0000000..d19109f --- /dev/null +++ b/beautiful-racket-demo/tacogram-demo/grammar.rkt @@ -0,0 +1,7 @@ +#lang brag +taco-program : /"\n"* taco-leaf* /"\n"* +taco-leaf : /left-paren (taco | not-a-taco){7} /right-paren +taco : /"%" +not-a-taco : /left-paren /right-paren +left-paren : "#" +right-paren : "$" \ No newline at end of file diff --git a/beautiful-racket-demo/tacogram-demo/main.rkt b/beautiful-racket-demo/tacogram-demo/main.rkt new file mode 100644 index 0000000..aa46241 --- /dev/null +++ b/beautiful-racket-demo/tacogram-demo/main.rkt @@ -0,0 +1,24 @@ +#lang br/quicklang +(require "grammar.rkt") + +(module+ reader + (provide read-syntax)) + +(define (tokenize ip) + (for/list ([tok (in-port read-char ip)]) + tok)) + +(define (leaf->char taco-leaf) + (integer->char + (for/sum ([val (in-list (cdr taco-leaf))] + [power (in-naturals)] + #:when (equal? val '(taco))) + (expt 2 power)))) + +(define (read-syntax src ip) + (define parse-tree (parse-to-datum (tokenize ip))) + (define taco-branches (cdr parse-tree)) + (strip-context + (with-syntax ([CHARS (map leaf->char taco-branches)]) + #'(module untaco racket + (display (list->string 'CHARS)))))) \ No newline at end of file diff --git a/beautiful-racket-demo/tacogram-demo/test.rkt b/beautiful-racket-demo/tacogram-demo/test.rkt new file mode 100644 index 0000000..1aef0b4 --- /dev/null +++ b/beautiful-racket-demo/tacogram-demo/test.rkt @@ -0,0 +1,2 @@ +#lang tacogram-demo +##$%#$%#$#$#$$##$%#$%#$#$#$$##$%#$#$#$%#$$##$#$#$%#$%%$#%#$%#$#$%%$##$#$%%#$%%$##$#$%%#$%%$#%%%%#$%%$##$#$#$#$#$%#$$#%%%#$%%%$#%%%%#$%%$##$%#$#$%%%$##$#$%%#$%%$##$#$%#$#$%%$##$%#$#$#$%#$$##$%#$%#$#$#$$##$#$#$%#$%#$$#%%#$%#$%#$$##$#$#$#$#$%#$$#%#$#$#$%%#$$##$#$#$#$#$%#$$##$#$#$%#$%#$$##$%#$%#$%#$$##$#$#$#$#$%#$$##$%#$#$%%#$$##$#$#$#$#$%#$$##$#$#$%#$%#$$#%#$%%#$%#$$##$#$#$#$#$%#$$#%%#$#$%%#$$#%#$#$%#$%#$$#%#$#$%#$%#$$#%#$#$%#$%#$$ \ No newline at end of file diff --git a/beautiful-racket-demo/tacopocalypse-demo/main.rkt b/beautiful-racket-demo/tacopocalypse-demo/main.rkt new file mode 100644 index 0000000..fa20bfd --- /dev/null +++ b/beautiful-racket-demo/tacopocalypse-demo/main.rkt @@ -0,0 +1,33 @@ +#lang br/quicklang +(require brag/support racket/sequence) + +(module+ reader + (provide read-syntax)) + +(define lex + (lexer + ["#$" null] + ["%" 'taco] + [any-char (lex input-port)])) + +(define (tokenize ip) + (define toklets + (for/list ([toklet (in-port lex ip)]) + toklet)) + (for/list ([tok (in-slice 7 toklets)]) + tok)) + +(define (parse taco-rec-tok) + (integer->char + (for/sum ([val (in-list taco-rec-tok)] + [power (in-naturals)] + #:when (eq? val 'taco)) + (expt 2 power)))) + +(define (read-syntax src ip) + (define toks (tokenize ip)) + (define parse-tree (map parse toks)) + (strip-context + (with-syntax ([PT parse-tree]) + #'(module untaco racket + (display (list->string 'PT)))))) \ No newline at end of file diff --git a/beautiful-racket-demo/tacopocalypse-demo/test.rkt b/beautiful-racket-demo/tacopocalypse-demo/test.rkt new file mode 100644 index 0000000..5125450 --- /dev/null +++ b/beautiful-racket-demo/tacopocalypse-demo/test.rkt @@ -0,0 +1,2 @@ +#lang tacopocalypse-demo +##$%#$%#$#$#$$##$%#$%#$#$#$$##$%#$#$#$%#$$##$#$#$%#$%%$#%#$%#$#$%%$##$#$%%#$%%$##$#$%%#$%%$#%%%%#$%%$##$#$#$#$#$%#$$#%%%#$%%%$#%%%%#$%%$##$%#$#$%%%$##$#$%%#$%%$##$#$%#$#$%%$##$%#$#$#$%#$$##$%#$%#$#$#$$##$#$#$%#$%#$$#%%#$%#$%#$$##$#$#$#$#$%#$$#%#$#$#$%%#$$##$#$#$#$#$%#$$##$#$#$%#$%#$$##$%#$%#$%#$$##$#$#$#$#$%#$$##$%#$#$%%#$$##$#$#$#$#$%#$$##$#$#$%#$%#$$#%#$%%#$%#$$##$#$#$#$#$%#$$#%%#$#$%%#$$#%#$#$%#$%#$$#%#$#$%#$%#$$#%#$#$%#$%#$$ \ No newline at end of file diff --git a/beautiful-racket-demo/tacopocalypse-prep/main.rkt b/beautiful-racket-demo/tacopocalypse-prep/main.rkt new file mode 100644 index 0000000..7c6c74a --- /dev/null +++ b/beautiful-racket-demo/tacopocalypse-prep/main.rkt @@ -0,0 +1,23 @@ +#lang br/quicklang +(require brag/support racket/sequence) + +(module+ reader + (provide read-syntax)) + +(define taco-lexer + (lexer + ["(" "#"] + [")" "$"] + ["taco" "%"] + [any-char (taco-lexer input-port)])) + +(define (read-syntax src port) + (define toks (for/list ([tok (in-port taco-lexer port)]) + tok)) + (define parse-tree (string-join toks "")) + + ;; print result + (strip-context + (with-syntax ([PT parse-tree]) + #'(module untaco racket + (display PT))))) \ No newline at end of file diff --git a/beautiful-racket-demo/tacopocalypse-prep/test.rkt b/beautiful-racket-demo/tacopocalypse-prep/test.rkt new file mode 100644 index 0000000..a413d84 --- /dev/null +++ b/beautiful-racket-demo/tacopocalypse-prep/test.rkt @@ -0,0 +1,34 @@ +#lang tacopocalypse-prep +(() taco () taco () () ()) +(() taco () taco () () ()) +(() taco () () () taco ()) +(() () () taco () taco taco) +(taco () taco () () taco taco) +(() () taco taco () taco taco) +(() () taco taco () taco taco) +(taco taco taco taco () taco taco) +(() () () () () taco ()) +(taco taco taco () taco taco taco) +(taco taco taco taco () taco taco) +(() taco () () taco taco taco) +(() () taco taco () taco taco) +(() () taco () () taco taco) +(() taco () () () taco ()) +(() taco () taco () () ()) +(() () () taco () taco ()) +(taco taco () taco () taco ()) +(() () () () () taco ()) +(taco () () () taco taco ()) +(() () () () () taco ()) +(() () () taco () taco ()) +(() taco () taco () taco ()) +(() () () () () taco ()) +(() taco () () taco taco ()) +(() () () () () taco ()) +(() () () taco () taco ()) +(taco () taco taco () taco ()) +(() () () () () taco ()) +(taco taco () () taco taco ()) +(taco () () taco () taco ()) +(taco () () taco () taco ()) +(taco () () taco () taco ()) \ No newline at end of file diff --git a/beautiful-racket-demo/xmlish-demo/grammar.rkt b/beautiful-racket-demo/xmlish-demo/grammar.rkt new file mode 100644 index 0000000..03bcc13 --- /dev/null +++ b/beautiful-racket-demo/xmlish-demo/grammar.rkt @@ -0,0 +1,19 @@ +#lang brag + +top : @content +content : (tagged-element | /comment | string | sp)* + +tagged-element : /"<" /sp? identifier attrs /sp? (short | full) +@short : /"/>" +@full : /">" content /"" + +attrs : [attr] (/sp attr)* +attr : identifier /sp? /"=" /sp? /"\"" string /"\"" + +comment : "" + +string : char+ +identifier : ALPHANUMERIC [@string] + +@sp : SP +@char : ALPHANUMERIC | OTHER | AMP | LT | GT | "=" | "\"" diff --git a/beautiful-racket-demo/xmlish-demo/main.rkt b/beautiful-racket-demo/xmlish-demo/main.rkt new file mode 100644 index 0000000..f0a2f71 --- /dev/null +++ b/beautiful-racket-demo/xmlish-demo/main.rkt @@ -0,0 +1,46 @@ +#lang br/quicklang +(require brag/support "grammar.rkt" xml) +(provide (all-from-out br/quicklang) (all-defined-out) xexpr?) + +(module+ reader + (provide read-syntax)) + +(define-lex-abbrev xml-reserved + (:or "<" "/>" "" "" "=" "\"")) + +(define lex + (lexer + [(:+ whitespace) (token 'SP " ")] + ["&" (token 'AMP "&")] + ["<" (token 'LT "<")] + [">" (token 'GT ">")] + [xml-reserved lexeme] + [(:or alphabetic numeric) (token 'ALPHANUMERIC lexeme)] + [any-char (token 'OTHER lexeme)])) + +(define (top . contents) `(root ,@contents)) +(define (content . xs) xs) + +(define-cases tagged-element + [(_ id attrs) (list id attrs)] + [(_ id attrs contents id-end) + (unless (eq? id id-end) + (raise-argument-error 'tagged-element "matched tags" (list id id-end))) + (list* id attrs contents)]) + +(define (attrs . attr-list) attr-list) +(define (attr id value) (list id value)) + +(define (string . strs) (string-join strs "")) +(define (identifier . strs) + (string->symbol (apply string strs))) + +(define (read-syntax src ip) + (define parse-tree (parse (λ () (lex ip)))) + (strip-context + (with-syntax ([PT parse-tree]) + #'(module mel xmlish-demo + (println PT) + (displayln (if (xexpr? PT) + "YES, it's an X-expression" + "NO, it's not an X-expression")))))) \ No newline at end of file diff --git a/beautiful-racket-demo/xmlish-demo/test.rkt b/beautiful-racket-demo/xmlish-demo/test.rkt new file mode 100644 index 0000000..c25bae7 --- /dev/null +++ b/beautiful-racket-demo/xmlish-demo/test.rkt @@ -0,0 +1,10 @@ +#lang xmlish-demo + +hello world +
+
+< div > +
hello world
+ +< p:foo foo="bar" zim= "42" >Hell = o World 42 "-!=" & > < +