what is the scheme (or lisp? idk) way to represent C enum like typedef enum WASMOpcode {
WASM_OP_UNREACHABLE = 0x00,
WASM_OP_NOP = 0x01,
...
}
(from https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/core/iwasm/interpreter/wasm_opcode.h)
IIUC, people usually use symbols instead. E.g., 'WASM-OP-UNREACHABLE
And you can define (define WASMOpcode/c (or/c 'WASM-OP-UNREACHABLE 'WASM_OP_NOP ...))
to be a contract to recognize these values
If you are willing to go beyond standard Racket libraries, some user libraries have the enum
concept that you can use. E.g., https://docs.racket-lang.org/rebellion/Enum_Types.html
Ah, I see. so the parser should be like (w/o libraries) (match byte
[#x00 'WASM-OP-UNREACHABLE]
[#x01 'WASM-OP-NOP]
...)
Can I use this style in typed racket too? or does any better way exist?
Oh, so you are dealing with external data with those enum values…
I mean, if you want to convert these external data into stuff like 'WASM-OP-UNREACHABLE
, that’s totally possible, and definitely can be done in #lang typed/racket
Something like:
#lang typed/racket
(define-type WASMOpcode
(U 'WASM-OP-UNREACHABLE
'WASM-OP-NOP))
(: test : Number -> WASMOpcode)
(define (test x)
(match x
[0 'WASM-OP-UNREACHABLE]
[1 'WASM-OP-NOP]))
But if you don’t want to parse, I guess you could also do:
(define WASM-OP-UNREACHABLE 0)
(define WASM-OP-NOP 1)
and use these identifiers?
If you don’t want to write consecutive numbers 0, 1, 2, …, you can also use macros to generate these numbers automatically.
If the context is writing a C API, then use _enum
. Otherwise, just use symbols.
Hi, how can I make a syntax-parse
macro that would expand to a module that I could write to a file without the calling code needing to (require file/module)
but only (require file)
, i.e. the macro expansion would be “spliced” inside the file?
Can you make your question a little more concrete, perhaps with an example of preciesely what you want to write?
This (define-syntax (i-expand-in-a-module stx)
(syntax-parse stx
[(_ s)
#'(module simplest-module-ever racket
s)]))
(with-output-to-file path (lambda () (write (i-expand-in-a-module (list 'a 'b 'c))))
expands to (module simplest-module-ever racket
;whatever 's' is)
in file.rkt
. Then, if I want to require this module I’d have to do (require file/simplest-module-ever)
, isn’t it? What I’d like is to write (require file)
and have simplest-module-ever
available. Is that possible?
I’m confused. That program does not do what you describe. It produces a syntax error, because you expanded to a module
form inside an application, which is not where modules go.
It’s certainly possible to have macros that expand to submodules which live inside other modules.
But in general macro-expansion doesn’t create new files on disk using write
.
Then there’s another question which is you’d like to be able to write (require a)
and have it actually require a/b.rkt
. You can certainly write a require transformer, called say f
, and then you could have (require (f a))
actually mean (require a/b.rkt)
. Would that be ok?
I’m confused myself. I understand the transformer bit. I’ll work some more to try to understand the source of my confusion and come back. Thank you for your time and kindness.
FWIW - it’s possible to use syntax-parse
in phase 0, so you don’t need to use a macro to construct your module.
@soegaard2 would that be done by wrapping the (syntax-parse ...
expression as (define (p0 arg) (syntax-parse arg ...
instead of (define-syntax (p0 stx) (syntax-parse stx ..
or is there some other trick to it? I can’t get it to work at phase 0 for now.
Something like this: #lang racket
(require syntax/parse)
(define (i-expand-in-a-module stx)
(syntax-parse stx
[s
#'(module simplest-module-ever racket
s)]))
(i-expand-in-a-module #'(list 'a 'b 'c))
This particular example could also be written as: (define (i-expand-in-a-module s)
(with-syntax ([s s])
#'(module simplest-module-ever racket
s)))
@raoul.schorer ^