first commit
This commit is contained in:
commit
6288f19e93
107
README.md
Normal file
107
README.md
Normal file
@ -0,0 +1,107 @@
|
||||
= turingAutomaton =
|
||||
|
||||
a toy programming language for creating turing machines
|
||||
|
||||
== description ==
|
||||
|
||||
`turingAutomaton` is a programming language created to test the Racket ecosystem. it features custom syntax and is able to run single tape turing machines.
|
||||
|
||||
== installation ==
|
||||
|
||||
```
|
||||
git clone https://git.lain.church/tA/turingAutomaton
|
||||
cd turingAutomaton
|
||||
raco pkg install
|
||||
```
|
||||
|
||||
== syntax ==
|
||||
|
||||
all files must begin with a
|
||||
|
||||
```
|
||||
#lang turingAutomaton
|
||||
```
|
||||
|
||||
followed by a definition of;
|
||||
|
||||
```
|
||||
@ beginningState
|
||||
% blankSymbol
|
||||
! acceptingState
|
||||
```
|
||||
|
||||
(currently the accepting state is unimplemented)
|
||||
|
||||
`states` are defined using the following syntax;
|
||||
|
||||
```
|
||||
: stateName
|
||||
currentSymbol ~ newSymbol > newState
|
||||
currentSymbol ~ newSymbol < newState
|
||||
```
|
||||
|
||||
where `<` and `>` denote moving the tape left and right, respectively
|
||||
|
||||
comments are allowed:
|
||||
|
||||
```
|
||||
; either on their own line
|
||||
@ first ; or at the end of a line
|
||||
```
|
||||
|
||||
== sample program ==
|
||||
|
||||
this machine will double a number passed to it
|
||||
|
||||
```
|
||||
#lang turingAutomaton
|
||||
|
||||
; this is a comment!
|
||||
|
||||
@ first
|
||||
% e
|
||||
! F
|
||||
|
||||
: first
|
||||
a ~ b > second
|
||||
c ~ c > fourth
|
||||
|
||||
: second
|
||||
a ~ a > second
|
||||
c ~ c > second
|
||||
e ~ c < third
|
||||
|
||||
: third
|
||||
a ~ a < third
|
||||
b ~ b > first
|
||||
c ~ c < third
|
||||
|
||||
: fourth
|
||||
c ~ c > fourth
|
||||
e ~ e < fifth
|
||||
|
||||
: fifth
|
||||
b ~ a < fifth
|
||||
c ~ a < fifth
|
||||
e ~ e > F
|
||||
```
|
||||
|
||||
== caveats ==
|
||||
|
||||
currently very unfinished.
|
||||
|
||||
all input is a single tape defined with `aaaaa` for now.
|
||||
|
||||
there is no error checking until I learn how to do that.
|
||||
|
||||
might get slow for very large tapes as the tape uses linked lists to operate.
|
||||
|
||||
== thanks ==
|
||||
|
||||
mutce ckire to:
|
||||
* the racket team for creating an awesome language
|
||||
* Matthew Butterick for his book [Beautiful Racket](https://beautifulracket.com/) and the libraries within
|
||||
|
||||
== author ==
|
||||
|
||||
`fi'e la ti'ei`
|
60
expander.rkt
Normal file
60
expander.rkt
Normal file
@ -0,0 +1,60 @@
|
||||
#lang br/quicklang
|
||||
|
||||
(require "tmUtils.rkt")
|
||||
|
||||
(define-macro (tA-module-begin PARSE-TREE)
|
||||
#'(#%module-begin
|
||||
PARSE-TREE
|
||||
(display-result '(a a a a a))))
|
||||
(provide (rename-out [tA-module-begin #%module-begin]))
|
||||
|
||||
(define-macro (tA-program START-ARG BLANK-ARG ACCEPT-ARG STATE-SET-ARG)
|
||||
#'(void START-ARG BLANK-ARG ACCEPT-ARG STATE-SET-ARG))
|
||||
(provide tA-program)
|
||||
|
||||
(define-macro (tA-start "@" START-ARG)
|
||||
#'(set-start! START-ARG))
|
||||
(provide tA-start)
|
||||
|
||||
(define-macro (tA-blank "%" BLANK-ARG)
|
||||
#'(set-def! BLANK-ARG))
|
||||
(provide tA-blank)
|
||||
|
||||
(define-macro (tA-accept "!" ACCEPT-ARG)
|
||||
#'(void))
|
||||
(provide tA-accept)
|
||||
|
||||
(define-macro (tA-state-set STATE-ARG ...)
|
||||
#'(begin
|
||||
STATE-ARG ...))
|
||||
(provide tA-state-set)
|
||||
|
||||
(define-macro (tA-tran CURRENT "~" NEW DIR NEXT)
|
||||
#'(lambda (i)
|
||||
(hash-set! trans-map
|
||||
`(,i ,CURRENT)
|
||||
`(,NEW ,DIR ,NEXT))))
|
||||
(provide tA-tran)
|
||||
|
||||
(define-macro (tA-tran-set TRAN ...)
|
||||
#'(lambda (i)
|
||||
(begin
|
||||
(TRAN i) ...)))
|
||||
(provide tA-tran-set)
|
||||
|
||||
(define-macro (tA-state ":" ID TRAN-SET)
|
||||
#'(TRAN-SET ID))
|
||||
(provide tA-state)
|
||||
|
||||
(define-macro (tA-state-id ID)
|
||||
#'(string->symbol ID))
|
||||
(provide tA-state-id)
|
||||
|
||||
(define-macro (tA-symbol SYM)
|
||||
#'(string->symbol SYM))
|
||||
(provide tA-symbol)
|
||||
|
||||
(define-macro (tA-dir DIR)
|
||||
#'(begin
|
||||
(if (equal? "<" DIR) 'L 'R)))
|
||||
(provide tA-dir)
|
4
main.rkt
Normal file
4
main.rkt
Normal file
@ -0,0 +1,4 @@
|
||||
#lang br/quicklang
|
||||
(module reader br
|
||||
(require "reader.rkt")
|
||||
(provide read-syntax))
|
13
parser.rkt
Normal file
13
parser.rkt
Normal file
@ -0,0 +1,13 @@
|
||||
#lang brag
|
||||
|
||||
tA-program : tA-start tA-blank tA-accept tA-state-set
|
||||
tA-start : "@" tA-state-id
|
||||
tA-blank : "%" tA-symbol
|
||||
tA-accept : "!" tA-state-id
|
||||
tA-state-set : tA-state (tA-state)*
|
||||
tA-state : ":" tA-state-id tA-tran-set
|
||||
tA-tran-set : (tA-tran)* (NL)*
|
||||
tA-tran : tA-symbol "~" tA-symbol tA-dir tA-state-id (NL)*
|
||||
tA-symbol : TA-STRING
|
||||
tA-state-id : TA-STRING
|
||||
tA-dir : "<" | ">"
|
26
reader.rkt
Normal file
26
reader.rkt
Normal file
@ -0,0 +1,26 @@
|
||||
#lang br/quicklang
|
||||
(require "parser.rkt")
|
||||
|
||||
(define (read-syntax path port)
|
||||
(define parse-tree (parse path (make-tokenizer port)))
|
||||
(define module-datum `(module tA-mod turingAutomaton/expander
|
||||
,parse-tree))
|
||||
(datum->syntax #f module-datum))
|
||||
(provide read-syntax)
|
||||
|
||||
(require brag/support)
|
||||
|
||||
(define-lex-abbrev digits (:+ (char-set "0123456789")))
|
||||
|
||||
(define (make-tokenizer port)
|
||||
(define (next-token)
|
||||
(define tA-lexer
|
||||
(lexer
|
||||
[(from/to ";" "\n") (next-token)]
|
||||
[whitespace (next-token)]
|
||||
["\n" (token 'NL lexeme)]
|
||||
[(char-set "@%!~<>") lexeme]
|
||||
[(:+ (:or digits alphabetic)) (token 'TA-STRING lexeme)]
|
||||
[any-char lexeme]))
|
||||
(tA-lexer port))
|
||||
next-token)
|
121
tmUtils.rkt
Normal file
121
tmUtils.rkt
Normal file
@ -0,0 +1,121 @@
|
||||
#lang racket
|
||||
|
||||
; utils - wont change
|
||||
|
||||
(define def-symbol '())
|
||||
(define start-state '())
|
||||
(define input '())
|
||||
|
||||
(define (set-def! x)
|
||||
(set! def-symbol x))
|
||||
|
||||
(define (set-start! x)
|
||||
(set! start-state x))
|
||||
|
||||
(define (set-input! x)
|
||||
(set! start-state x))
|
||||
|
||||
(define (pre t)
|
||||
(car t))
|
||||
|
||||
(define (cur t)
|
||||
(cadr t))
|
||||
|
||||
(define (aft t)
|
||||
(caddr t))
|
||||
|
||||
(define (shiftr t)
|
||||
(let* [(c (cur t))
|
||||
(p (pre t))
|
||||
(a (aft t))
|
||||
(a (if (null? a)
|
||||
(list def-symbol)
|
||||
a))]
|
||||
`(,(append p (list c))
|
||||
,(car a)
|
||||
,(cdr a))))
|
||||
|
||||
(define (shiftl t)
|
||||
(let* [(c (cur t))
|
||||
(p (pre t))
|
||||
(a (aft t))
|
||||
(p (if (null? p)
|
||||
(list def-symbol)
|
||||
p))]
|
||||
`(,(reverse (cdr (reverse p)))
|
||||
,(car (reverse p))
|
||||
,(cons c a))))
|
||||
|
||||
(define (write-sym s t)
|
||||
(let [(p (pre t))
|
||||
(a (aft t))]
|
||||
`(,p ,s ,a)))
|
||||
|
||||
(define (list->tape l)
|
||||
`(() ,(car l) ,(cdr l)))
|
||||
|
||||
(define trans-map (make-hash))
|
||||
|
||||
(define (transition current-state tape)
|
||||
(let [(f (hash-ref trans-map `(,current-state ,(cur tape)) #f))]
|
||||
(if (eq? f #f)
|
||||
`(,current-state ,tape)
|
||||
(let* [(new-sym (first f))
|
||||
(dir (second f))
|
||||
(new-state (third f))
|
||||
(dir-op (if (eq? 'L dir)
|
||||
shiftl
|
||||
shiftr))
|
||||
(new-tape (dir-op (write-sym new-sym tape)))]
|
||||
(transition new-state new-tape)))))
|
||||
|
||||
(define (tape->list t)
|
||||
(let [(flat-tape (append (pre t) (list (cur t)) (aft t)))
|
||||
(f (lambda (x) (eq? x def-symbol)))]
|
||||
(reverse (drop-while f (reverse (drop-while f flat-tape))))))
|
||||
|
||||
(define (drop-while f l)
|
||||
(if (null? l)
|
||||
l
|
||||
(if (f (car l))
|
||||
(drop-while f (cdr l))
|
||||
l)))
|
||||
|
||||
(define (display-result input)
|
||||
(let* [(res (transition start-state (list->tape input)))
|
||||
(fin-state (car res))
|
||||
(fin-tape (tape->list (cadr res)))]
|
||||
(void
|
||||
(printf "Initial State: ~a~nInitial Tape:~n~a~nFinal State: ~a~nFinal Tape:~n~a~n" start-state input fin-state fin-tape))))
|
||||
|
||||
(provide trans-map)
|
||||
(provide display-result)
|
||||
(provide set-def!)
|
||||
(provide set-start!)
|
||||
|
||||
;; per machine - will change
|
||||
;
|
||||
;(define def-symbol 'e)
|
||||
;(define start-state '1)
|
||||
;
|
||||
;(hash-set! trans-map '(1 a) '(b R 2))
|
||||
;(hash-set! trans-map '(1 c) '(c R 4))
|
||||
;
|
||||
;(hash-set! trans-map '(2 a) '(a R 2))
|
||||
;(hash-set! trans-map '(2 c) '(c R 2))
|
||||
;(hash-set! trans-map '(2 e) '(c L 3))
|
||||
;
|
||||
;(hash-set! trans-map '(3 a) '(a L 3))
|
||||
;(hash-set! trans-map '(3 c) '(c L 3))
|
||||
;(hash-set! trans-map '(3 b) '(b R 1))
|
||||
;
|
||||
;(hash-set! trans-map '(4 c) '(c R 4))
|
||||
;(hash-set! trans-map '(4 e) '(e L 5))
|
||||
;
|
||||
;(hash-set! trans-map '(5 c) '(a L 5))
|
||||
;(hash-set! trans-map '(5 b) '(a L 5))
|
||||
;(hash-set! trans-map '(5 e) '(e R F))
|
||||
;
|
||||
;; fin
|
||||
;
|
||||
;(display-result '(a a a a a))
|
Loading…
Reference in New Issue
Block a user