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")
|
(require "runtime.rkt" "prims.rkt")
|
||||||
|
|
||||||
|
|
||||||
(provide include-algol)
|
(provide include-algol literal-algol)
|
||||||
|
|
||||||
(define-syntax (include-algol stx)
|
(define-syntax (include-algol stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
|
@ -35,4 +35,21 @@
|
||||||
(current-load-relative-directory)
|
(current-load-relative-directory)
|
||||||
(current-directory))))
|
(current-directory))))
|
||||||
#'here)
|
#'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)])))
|
#'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|.}
|
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}
|
@section{Language}
|
||||||
|
|
||||||
The DrRacket and @racket[include-algol] implementation departs from
|
The DrRacket and @racket[include-algol] implementation departs from
|
||||||
|
|
|
@ -485,7 +485,7 @@
|
||||||
[(_ clause ...)
|
[(_ clause ...)
|
||||||
(let ([clauses (syntax->list #'(clause ...))])
|
(let ([clauses (syntax->list #'(clause ...))])
|
||||||
(let-values ([(start grammar cfg-error parser-clauses)
|
(let-values ([(start grammar cfg-error parser-clauses)
|
||||||
(let ([all-toks (apply
|
(let ([all-toks (apply
|
||||||
append
|
append
|
||||||
(map (lambda (clause)
|
(map (lambda (clause)
|
||||||
(syntax-case clause (tokens)
|
(syntax-case clause (tokens)
|
||||||
|
|
|
@ -125,8 +125,8 @@
|
||||||
(tokens non-terminals)
|
(tokens non-terminals)
|
||||||
(start <program>)
|
(start <program>)
|
||||||
(end EOF)
|
(end EOF)
|
||||||
(error (lambda (a b stx)
|
(error (lambda (_ name stx start end)
|
||||||
(raise-read-error (format "parse error near ~a" (syntax-e stx))
|
(raise-read-error (format "parse error near ~a" name)
|
||||||
(syntax-source stx)
|
(syntax-source stx)
|
||||||
(syntax-line stx)
|
(syntax-line stx)
|
||||||
(syntax-column 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