implement print
and goto
This commit is contained in:
parent
36ca9f1442
commit
6962bc331d
|
@ -6,37 +6,51 @@
|
|||
|
||||
(define #'(basic-module-begin PARSE-TREE ...)
|
||||
#'(#%module-begin
|
||||
'PARSE-TREE ...))
|
||||
PARSE-TREE ...))
|
||||
|
||||
(define #'(basic-program LINE ...)
|
||||
#'(begin
|
||||
(define program-lines (vector LINE ...))
|
||||
(run program-lines)))
|
||||
#'(basic-run LINE ...))
|
||||
|
||||
(define (run program-lines)
|
||||
(define (basic-run . lines)
|
||||
(define program-lines (list->vector (filter (λ(x) x) lines)))
|
||||
(for/fold ([line-idx 0])
|
||||
([i (in-naturals)]
|
||||
#:break (= line-idx (vector-length program-lines)))
|
||||
(match-define (list line-number proc jump-number)
|
||||
(match-define (cons line-number proc)
|
||||
(vector-ref program-lines line-idx))
|
||||
(when proc (proc))
|
||||
(if jump-number
|
||||
(for/first ([idx (in-range (vector-length program-lines))]
|
||||
#:when (= (car (vector-ref program-lines idx)) jump-number))
|
||||
idx)
|
||||
(define maybe-jump-number (and proc (proc)))
|
||||
(if (number? maybe-jump-number)
|
||||
(let ([jump-number maybe-jump-number])
|
||||
(for/or ([idx (in-range (vector-length program-lines))])
|
||||
(and (= (car (vector-ref program-lines idx)) jump-number)
|
||||
idx)))
|
||||
(add1 line-idx))))
|
||||
|
||||
;; model each line as (list line-number line-thunk jump)
|
||||
;; if jump is #f, that means go to the next line
|
||||
;; a `GOTO` would not have a line-thunk, just a jump
|
||||
;; what about `GOSUB`? A jump with a return jump ...
|
||||
;; model each line as (cons line-number line-thunk)
|
||||
(define-cases #'line
|
||||
[#'(line 'end) #'(list #f #f #f)]
|
||||
[#'(_ NUMBER (statement ARG ...) 'end) #'(list NUMBER (statement ARG ...) #f)]
|
||||
[#'(_ (statement ARG ...) 'end) #'(list #f (statement ARG ...) #f)])
|
||||
[#'(line 'end) #'#f]
|
||||
[#'(_ NUMBER STATEMENT 'end) #'(cons NUMBER (λ _ STATEMENT))]
|
||||
[#'(_ STATEMENT 'end) #'(cons #f (λ _ STATEMENT))])
|
||||
|
||||
(define #'(statement NAME ARG ...) #'(NAME ARG ...))
|
||||
|
||||
(define #'(expression ITEM) #'ITEM)
|
||||
(define #'(unsignedexpr ITEM) #'ITEM)
|
||||
(define #'(term ITEM) #'ITEM)
|
||||
(define #'(factor ITEM) #'ITEM)
|
||||
(define #'(number ITEM) #'ITEM)
|
||||
|
||||
(define #'(printitem EXPR-OR-STRING) #'EXPR-OR-STRING)
|
||||
|
||||
(define #'(printlist ITEM-OR-SEPARATOR ...) #'(list ITEM-OR-SEPARATOR ...))
|
||||
|
||||
(define (PRINT args)
|
||||
(for-each display args)
|
||||
(displayln ""))
|
||||
|
||||
(define (GOTO where)
|
||||
where)
|
||||
|
||||
(define-cases #'statement
|
||||
[#'(_ "PRINT" EXPR-LIST) #'(λ _ (begin (for-each display EXPR-LIST) (displayln "")))])
|
||||
|
||||
(define-cases #'expr-list
|
||||
[#'(_ EXPR ...) #'(list EXPR ...)])
|
||||
|
|
|
@ -1,32 +1,55 @@
|
|||
#lang ragg
|
||||
;; adapted from http://www.ittybittycomputers.com/IttyBitty/TinyBasic/TBuserMan.txt
|
||||
|
||||
basic-program : line*
|
||||
|
||||
line : CR | NUMBER statement CR | statement CR
|
||||
| NUMBER statement | statement
|
||||
line : NUMBER statement CR | statement CR | CR
|
||||
|
||||
statement : "PRINT" expr-list
|
||||
| "IF" expression relop expression "THEN" statement
|
||||
| "GOTO" expression
|
||||
| "INPUT" var-list
|
||||
statement : "PRINT" printlist
|
||||
| "PR" printlist
|
||||
| "INPUT" varlist
|
||||
| "LET" var "=" expression
|
||||
| var "=" expression
|
||||
| "GOTO" expression
|
||||
| "GOSUB" expression
|
||||
| "RETURN"
|
||||
| "IF" expression relop expression "THEN" statement
|
||||
| "IF" expression relop expression statement
|
||||
;| "REM" commentstring ; todo: implement in tokenizer
|
||||
| "CLEAR"
|
||||
| "LIST"
|
||||
| "RUN"
|
||||
| "END"
|
||||
| "RUN" exprlist
|
||||
| "LIST"
|
||||
| "LIST" exprlist
|
||||
|
||||
expr-list : (STRING | expression) ("," (STRING | expression) )*
|
||||
printlist : printitem [(":" | separator printlist)]
|
||||
|
||||
var-list : var ("," var)*
|
||||
printitem : expression | STRING
|
||||
|
||||
expression : term (("+"|"-") term)*
|
||||
varlist: var ["," varlist]
|
||||
|
||||
term : factor (("*"|"/") factor)*
|
||||
exprlist : expression ["," exprlist]
|
||||
|
||||
factor : var | NUMBER | (expression)
|
||||
expression : [("+"|"-")] unsignedexpr
|
||||
|
||||
unsignedexpr : term [("+"|"-") unsignedexpr]
|
||||
|
||||
term : factor [("*"|"/") term]
|
||||
|
||||
factor : var
|
||||
| number
|
||||
| "(" expression ")"
|
||||
| function
|
||||
|
||||
function : "RND(" expression ")"
|
||||
| "USR(" exprlist ")"
|
||||
|
||||
number : NUMBER
|
||||
|
||||
separator : "," | ";"
|
||||
|
||||
var : UPPERCASE
|
||||
|
||||
relop : "<" (">"|"="|"ε") | ">" ("<"|"="|"ε") | "="
|
||||
digit: DIGIT
|
||||
|
||||
relop : "<" [("="|">")] | ">" [("="|"<")] | "="
|
|
@ -1,2 +1,7 @@
|
|||
#lang br/basic
|
||||
20 GOTO 10
|
||||
10 PRINT "shit"
|
||||
20 PRINT "bird"
|
||||
25 PRINT "dork"
|
||||
30 GOTO 10
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
["\n" (token 'CR ''end)]
|
||||
[(union "PRINT" "IF" "THEN" "GOTO"
|
||||
"INPUT" "LET" "GOSUB" "RETURN"
|
||||
"CLEAR" "LIST" "RUN" "END") lexeme]
|
||||
"CLEAR" "LIST" "RUN" "END") (string->symbol lexeme)]
|
||||
;; this only matches integers
|
||||
[(repetition 1 +inf.0 numeric) (token 'NUMBER (string->number lexeme))]
|
||||
[(char-set ",+-ε*/<>=") lexeme]
|
||||
|
|
Loading…
Reference in New Issue
Block a user