Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error traces now point within .arc files #151

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 75 additions & 20 deletions ac.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
openssl
racket/string
racket/random
syntax/stx

(only-in "brackets.rkt" bracket-readtable)

Expand Down Expand Up @@ -103,17 +104,47 @@
([anarki-init-in-main-namespace-func anarki-init-verbose])
(anarki-init-in-main-namespace)))


(print-hash-table #t)
(print-syntax-width 10000)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use global state in the ac.rkt module. All the initialization steps should be possible to run multiple times by calling anarki-init, preferably with some way for Racket code to keep the settings of different instances isolated from each other.


; sread = scheme read. eventually replace by writing read

(define (sread p (eof eof))
(parameterize ((read-accept-lang #t)
(read-accept-reader #t))
(port-count-lines! p)
(let ((expr (read-syntax (object-name p) p)))
(if (eof-object? expr) eof expr))))

(define (syn x (src #f))
(if (syntax? x)
(syn (syntax->datum x) (or src x))
(datum->syntax #f x (if (syntax? src) src #f))))

(define (datum x)
(let ((s (syn x)))
(syntax->datum s)))

(define env* (make-parameter (list)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please allocate global stateful objects like this by using an xdef so it's carried in the Arc namespace and initialized by anarki-init. That way Racket code can pass around multiple instances of Anarki by passing around their namespaces.


; compile an Arc expression into a Scheme expression,
; both represented as s-expressions.
; env is a list of lexically bound variables, which we
; need in order to decide whether set should create a global.

(defarc (ac s env)
(define (stx-map proc stxl)
(map proc (stx->list stxl)))

(defarc (ac* e s env)
(cond [(string? s) (ac-string s env)]
[(literal? s) (list 'quote s)]
[(keyword? s) s]
[(literal? s) (list 'quote (ac-quoted s))]
[(eqv? s 'nil) (list 'quote 'nil)]
[(ssyntax? s) (ac (expand-ssyntax s) env)]
[(symbol? s) (ac-var-ref s env)]
[(eq? (xcar s) 'syntax) (cadr (syntax-e e))]
[(eq? (xcar (xcar s)) 'syntax) (stx-map ac e)]
[(ssyntax? (xcar s)) (ac (cons (expand-ssyntax (car s)) (cdr s)) env)]
[(eq? (xcar s) '$) (ac-$ (cadr s) env)]
[(eq? (xcar s) 'quote) (list 'quote (ac-quoted (ac-niltree (cadr s))))]
Expand All @@ -131,8 +162,17 @@
(ac (list 'no (cons (cadar s) (cdr s))) env)]
[(eq? (xcar (xcar s)) 'andf) (ac-andf s env)]
[(pair? s) (ac-call (car s) (cdr s) env)]
[(syntax? s) s]
[#t (err "Bad object in expression" s)]))

(defarc (ac stx (env (env*)) (ns main-namespace))
(parameterize ((env* env))
(let* ((s (syn stx))
(e (syntax->datum s))
(expr (ac* s e env)))
(parameterize ((current-namespace ns))
(namespace-syntax-introduce (syn expr stx))))))

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gosh, this is where the magic happens, isn't it? A well-placed namespace-syntax-introduce.

I just noticed you call (ac* s e env) here, but ac* is defined by (defarc (ac* e s env) ...).

(define (ac-string s env)
(if (ar-bflag 'atstrings)
(if (atpos s 0)
Expand Down Expand Up @@ -539,16 +579,21 @@

(define (ac-set1 a b1 env)
(if (symbol? a)
(let ([b (ac b1 (ac-dbname! a env))])
(list 'let `([zz ,b])
(cond [(eqv? a 'nil) (err "Can't rebind nil")]
[(eqv? a 't) (err "Can't rebind t")]
[(lex? a env) `(set! ,a zz)]
[(ac-defined-var? a) `(,(ac-global-name a) zz)]
[#t `(set! ,(ac-global-name a) zz)])
'zz))
(let ((n (string->symbol (string-append " " (symbol->string a))))
(b (ac b1 (ac-dbname! a env))))
(list 'let `((,n ,b))
(cond ((eqv? a 'nil) (err "Can't rebind nil"))
((eqv? a 't) (err "Can't rebind t"))
((eqv? a 'true) (err "Can't rebind true"))
((eqv? a 'false) (err "Can't rebind false"))
((eqv? a 'null) (err "Can't rebind null"))
((lex? a env) `(set! ,a ,n))
[(ac-defined-var? a) `(,(ac-global-name a) ,n)]
(#t `(set! ,(ac-global-name a) ,n)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you put the square brackets back here? Or if there was a reason you changed them, why did you leave one pair?

n))
(err "First arg to set must be a symbol" a)))


; given a list of Arc expressions, return a list of Scheme expressions.
; for compiling passed arguments.

Expand Down Expand Up @@ -610,7 +655,7 @@

(define (ac-macro? fn)
(if (symbol? fn)
(let ([v (and (bound? fn) (arc-eval fn))])
(let ([v (and (bound? fn) (bound fn))])
(if (and v
(ar-tagged? v)
(eq? (ar-type v) 'mac))
Expand Down Expand Up @@ -936,6 +981,7 @@
((async-channel? x) 'channel)
((evt? x) 'event)
[(keyword? x) 'keyword]
[(syntax? x) 'syntax]
[#t (err "Type: unknown type" x)]))
(xdef type ar-type)

Expand Down Expand Up @@ -1050,9 +1096,10 @@

; sread = scheme read. eventually replace by writing read

(xdef sread (lambda (p)
(let ([expr (read p)])
(xdef sdata (lambda (p (eof eof))
(let ((expr (read p)))
(if (eof-object? expr) eof expr))))
(xdef sread sread)

; these work in PLT but not scheme48

Expand Down Expand Up @@ -1316,10 +1363,13 @@
;
(define (arc-exec racket-expr)
(eval (parameterize ([compile-allow-set!-undefined #t])
(compile racket-expr))))
(if (syntax? racket-expr)
(compile-syntax (namespace-syntax-introduce racket-expr))
(compile racket-expr)))))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kinda love seeing this branch for some reason. At first it seemed to clarify a lot about your approach. But as I think about it, what if the expression starts off with a non-syntax list and then has syntax objects inside?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I got all kinds of context mixed up here. This is the Racket compile and compile-syntax. XD


(define (arc-eval expr)
(arc-exec (ac expr '())))
(define (arc-eval expr (env (env*)))
(parameterize ((env* env))
(arc-exec (ac expr))))

(define (tle)
(display "Arc> ")
Expand Down Expand Up @@ -1412,15 +1462,15 @@ Arc 3.1 documentation: https://arclanguage.github.io/ref.
(xdef current-fn current-fn))

(define (aload1 p)
(let ([x (read p)])
(let ([x (sread p)])
(if (eof-object? x)
(void)
(begin
(arc-eval x)
(aload1 p)))))

(define (atests1 p)
(let ([x (read p)])
(let ([x (sread p)])
(if (eof-object? x)
#t
(begin
Expand Down Expand Up @@ -1479,10 +1529,10 @@ Arc 3.1 documentation: https://arclanguage.github.io/ref.
(call-with-line-counting-input-file filename atests1))

(define (acompile1 ip op)
(let ([x (read ip)])
(let ([x (sread ip)])
(if (eof-object? x)
#t
(let ([scm (ac x '())])
(let ([scm (ac x)])
(arc-exec scm)
(pretty-print scm op)
(newline op)
Expand Down Expand Up @@ -1596,6 +1646,11 @@ Arc 3.1 documentation: https://arclanguage.github.io/ref.
(namespace-variable-value (ac-global-name arcname))
#t))

(define (bound arcname)
(with-handlers ([exn:fail:syntax? (lambda (e) #t)]
[exn:fail:contract:variable? (lambda (e) #f)])
(namespace-variable-value (ac-global-name arcname))))

(xdef bound (lambda (x) (tnil (bound? x))))

(xdef newstring make-string)
Expand Down
16 changes: 8 additions & 8 deletions arc.arc
Original file line number Diff line number Diff line change
Expand Up @@ -1557,17 +1557,17 @@ read from the stream 'str'."
(tostring ,@body)
,dest))

(def readstring1 (s)
(def readstring1 (s (o data t))
"Reads a single expression from string 's'. Returns the uninterned symbol
stored as the global value of 'eof' if there's nothing left to read."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, not that this is directly related to this change, but you've changed eof recently, right? I know you make the type of a bunch of things 'sym, which surprises me but not in a way I can really quantify, and I've been meaning to ask how you think of symbols as a concept.

(w/instring i s (read i)))
(w/instring i s (read i data)))

(def read ((o x (stdin)))
(def read ((o x (stdin)) (o data t))
"Reads a single expression from string or stream 'x'. Returns the uninterned
symbol stored as the global value of 'eof' if there's nothing left to read."
(if (isa x 'string)
(readstring1 x)
(sread x)))
(readstring1 x data)
((if data sdata sread) x)))

(mac fromfile (f . body)
"Redirects standard input from the file 'f' within 'body'."
Expand Down Expand Up @@ -2859,10 +2859,10 @@ of 'x' by calling 'self'."
(map (fn ((k v)) (= h.k unserialize.v))
rep*.x)))

(redef read ((o x (stdin)))
(redef read ((o x (stdin)) (o data t))
(if (isa x 'string)
(readstring1 x)
(unserialize:sread x)))
(readstring1 x data)
(unserialize ((if data sdata sread) x))))

(def write (x (o port (stdout)))
(swrite serialize.x port))
Expand Down