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:
Robby Findler 2012-06-20 10:27:28 -05:00
parent 8f892a2d3a
commit c0b928c758
5 changed files with 100 additions and 4 deletions

View File

@ -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)])))

View File

@ -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

View File

@ -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)

View File

@ -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)

View 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}))