sydney.lambda
2020-1-3 05:03:52

Would appreciate some advice, hit a bit of a wall with my lang. The language I’m trying to implement is basically just these functions: https://github.com/dys-bigwig/stacklang/blob/master/s.rkt So the full module using the lang is just transformed into a big composed function and then applied to an empty stack. This is working great for 1 2 plus expressions, but I’m struggling to implement quotations. They’re - nestable - delayed functions that are pushed to the stack, and can then either be used as arguments to other functions which expect them on the stack, or executed directly on the stack using i: 1 < 1 < + > > i i will produce 2, as the first i causes the now unquoted literal 1 to be pushed to the stack, and then the second i causes the < + > left on the stack by the previous i to be called, adding the two 1s. I have this behavior implemented in racket in the s.rkt file, but attempting to expand my lang into this doesn’t work. For example: 1 < 3 + > rather than ending up with a stack like (<3 +> 1) yields: application: not a procedure; expected a procedure that can be applied to arguments given: '(3 . #<procedure:...t/stack/main.rkt:35:26>) . I think it’s because the expressions/syntax nested in the quotations are being evaluated, rather than remaining as (number 1) and (identifier plus) ? Can anybody please help me diagnose the error and point me in the right direction? I figured it would be a pretty straightforward conversion from the racket implementation to the lang, but it’s proving to be a bit more difficult. I looked into local-expand and other things that sounded somewhat relevant, but I’m really not sure where to go from here. Quoting them using racket’s quote of course leaves them unexpanded, but then I imagine I’d have to get into using eval, and that just seems like a bad approach in general. If you reached here, thank you so much for taking the time to read it, I’d really appreciate some help progressing with this.


sydney.lambda
2020-1-3 05:40:00

I did it! I wrapped them in a prefab struct as part of the quotation.


sydney.lambda
2020-1-3 05:40:22

Hopefully that’s an acceptable approach?


notjack
2020-1-3 05:42:08

@sydney.lambda I think the problem is your stack-module-begin macro:

(define-syntax-rule (stack-module-begin body ...) (#%plain-module-begin (display ((stack-compose body ...) empty)))) With that macro exported as #%module-begin, a file like this:

#lang stacklang 1 < 1 < + > > i i …will expand into this:

(display ((stack-compose 1 < 1 < + > > i i) empty)) …when it seems like you want it to expand into this:

(display ((stack-compose (list (num 1) (quot (num 1) (quot add)) i i)) empty))


sydney.lambda
2020-1-3 05:45:21

Now I’m really confused, haha. I thought all the subforms were being expanded into their procedural equivalents and then passed to stack-compose.


sydney.lambda
2020-1-3 05:46:46

Is that not what you’d normally want?


sydney.lambda
2020-1-3 05:47:58

The only thing I could find resembling a tutorial for this “have a macro for every wrapped piece of AST the parser produces” approach used mutable set! macros with a shared structure, so this issue of combining forms didn’t come up at all.


notjack
2020-1-3 05:51:36

The (stack-compose body …) part of the template of stack-module-begin means that the body … parts are copied exactly as they were given to stack-module-begin .


notjack
2020-1-3 05:54:00

Oh wait, I totally missed that you have a lang/reader.rkt file that sets up the reader.


notjack
2020-1-3 05:54:42

You can ignore my earlier comment


sydney.lambda
2020-1-3 05:57:51

phew I was really starting to get worried there, haha. Thanks for taking the time to look over it. If you do see anything that is weird, please let me know. This is my first lang and although there’s a lot of documentation on this subject, I’m a learn-via-tutorials kind of person so this is proving to be a challenge.