Added @literal-algol{} and started an algol60 test suite (apologies
if there already was one that I didn't find). Also fixed syntax error raising procedure. closes PR 12859
This commit is contained in:
parent
8f892a2d3a
commit
c0b928c758
|
@ -20,7 +20,7 @@
|
|||
(require "runtime.rkt" "prims.rkt")
|
||||
|
||||
|
||||
(provide include-algol)
|
||||
(provide include-algol literal-algol)
|
||||
|
||||
(define-syntax (include-algol stx)
|
||||
(syntax-case stx ()
|
||||
|
@ -35,4 +35,21 @@
|
|||
(current-load-relative-directory)
|
||||
(current-directory))))
|
||||
#'here)
|
||||
#'here)]))
|
||||
|
||||
(define-syntax (literal-algol stx)
|
||||
(syntax-case stx ()
|
||||
[(_ strs ...)
|
||||
(andmap (λ (x) (string? (syntax-e x)))
|
||||
(syntax->list (syntax (strs ...))))
|
||||
|
||||
(compile-simplified
|
||||
(simplify
|
||||
(parse-a60-port
|
||||
(open-input-string
|
||||
(apply
|
||||
string-append
|
||||
(map syntax-e (syntax->list #'(strs ...)))))
|
||||
(syntax-source stx))
|
||||
#'here)
|
||||
#'here)])))
|
||||
|
|
|
@ -26,6 +26,25 @@ closed (i.e., it doesn't see any bindings in the included context),
|
|||
and the result is always @|void-const|.}
|
||||
|
||||
|
||||
@defform[(literal-algol string ...)]{
|
||||
|
||||
Evaluates the Algol 60 program indicated by the literal @racket[string]s
|
||||
as an expression in a Racket program. The Algol 60 program is
|
||||
closed (i.e., it doesn't see any bindings in the included context),
|
||||
and the result is always @|void-const|.
|
||||
|
||||
This is generally useful when combined with the @racketmodname[at-exp] reader,
|
||||
e.g.,
|
||||
@codeblock|{
|
||||
#lang at-exp racket
|
||||
@literal-algol{
|
||||
begin
|
||||
printsln (`hello world')
|
||||
end
|
||||
}
|
||||
}|
|
||||
}
|
||||
|
||||
@section{Language}
|
||||
|
||||
The DrRacket and @racket[include-algol] implementation departs from
|
||||
|
|
|
@ -485,7 +485,7 @@
|
|||
[(_ clause ...)
|
||||
(let ([clauses (syntax->list #'(clause ...))])
|
||||
(let-values ([(start grammar cfg-error parser-clauses)
|
||||
(let ([all-toks (apply
|
||||
(let ([all-toks (apply
|
||||
append
|
||||
(map (lambda (clause)
|
||||
(syntax-case clause (tokens)
|
||||
|
|
|
@ -125,8 +125,8 @@
|
|||
(tokens non-terminals)
|
||||
(start <program>)
|
||||
(end EOF)
|
||||
(error (lambda (a b stx)
|
||||
(raise-read-error (format "parse error near ~a" (syntax-e stx))
|
||||
(error (lambda (_ name stx start end)
|
||||
(raise-read-error (format "parse error near ~a" name)
|
||||
(syntax-source stx)
|
||||
(syntax-line stx)
|
||||
(syntax-column stx)
|
||||
|
|
60
collects/tests/algol60/test.rkt
Normal file
60
collects/tests/algol60/test.rkt
Normal file
|
@ -0,0 +1,60 @@
|
|||
#lang at-exp racket/base
|
||||
(require algol60/algol60
|
||||
rackunit
|
||||
(for-syntax racket/base))
|
||||
|
||||
(define-syntax (capture-output stx)
|
||||
(syntax-case stx ()
|
||||
[(_ exp)
|
||||
(with-handlers ((exn:fail?
|
||||
(λ (exn)
|
||||
#`(list 'expand
|
||||
#,(exn-message exn)))))
|
||||
(define expanded (local-expand #'exp 'expression #f))
|
||||
#`(let ([op (open-output-string)]
|
||||
[ep (open-output-string)])
|
||||
(let/ec k
|
||||
(parameterize ([current-output-port op]
|
||||
[current-error-port ep]
|
||||
[error-escape-handler (λ () (k (void)))])
|
||||
#,expanded))
|
||||
(list 'run
|
||||
(get-output-string op)
|
||||
(get-output-string ep))))]))
|
||||
|
||||
(check-equal?
|
||||
(capture-output
|
||||
@literal-algol{
|
||||
begin
|
||||
printsln (`hello world')
|
||||
end
|
||||
})
|
||||
'(run "hello world\n" ""))
|
||||
|
||||
(check-pred
|
||||
(λ (x) (and (eq? (list-ref x 0) 'expand)
|
||||
(regexp-match #rx"parse error near BEGIN"
|
||||
(list-ref x 1))))
|
||||
(capture-output
|
||||
@literal-algol{
|
||||
begin
|
||||
}))
|
||||
|
||||
|
||||
(check-pred
|
||||
(λ (x) (and (eq? (list-ref x 0) 'expand)
|
||||
(regexp-match #rx"parse error near PROCEDURE"
|
||||
(list-ref x 1))))
|
||||
(capture-output
|
||||
@literal-algol{
|
||||
procedure Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k);
|
||||
value n, m; array a; integer n, m, i, k; real y;
|
||||
begin integer p, q;
|
||||
y := 0; i := k := 1;
|
||||
for p:=1 step 1 until n do
|
||||
for q:=1 step 1 until m do
|
||||
if abs(a[p, q]) > y then
|
||||
begin y := abs(a[p, q]);
|
||||
i := p; k := q
|
||||
end
|
||||
end Absmax}))
|
Loading…
Reference in New Issue
Block a user