I would like to define a macro that can define more macros as:
define(`master_macro',
`foreachq(`slave_macro', `$*',
define(`slave_macro', ...)'
then I can use master_macro to define more similar slave_macros as:
master_macro(m1, m2, m3, ...)
The reason why I need this is that the number and names of slave_macro are unknown when I write M4 macros.
What you are asking for can certainly be done. Here's an example:
$ cat file
changequote(`[',`]')dnl
define([factory],[dnl
define($1,banana)dnl
define($2,split)dnl
])dnl
factory(hello,world)dnl
hello world
$ m4 file
banana split
I think the problem is your usage of the undefined macro foreachq.
Related
Reading the docs of the m4 macro language I have found that example:
changequote([,])dnl
define([gl_STRING_MODULE_INDICATOR],
[dnl comment
GNULIB_[]translit([[$1]], [a-z], [A-Z])=1dnl
])dnl
gl_STRING_MODULE_INDICATOR([strcase])
which produces:
GNULIB_STRCASE=1
But if one omits to quote strcase we have the same result:
gl_STRING_MODULE_INDICATOR(strcase)
produces
GNULIB_STRCASE=1
Why quoting strcase?
The quotes are required in case strcase is defined as a macro. For example, if we have define(strcase, foo), then gl_STRING_MODULE_INDICATOR(strcase) will expand first into gl_STRING_MODULE_INDICATOR(foo) and then into GNULIB_FOO=1.
In general, well-written m4 input will continue to function when certain words unexpectedly happen to be defined as macros.
I want to pass in a config like:
foo
blah.bar: blah.bar
another.thing: some.thing
And I want to do this on the commmandline, osmething like:
python my_script.py foo.blah.bar=blah.bar foo.another.thing=some.thing
Obviously, this would give me instead:
foo
blah
bar: blah.bar
another
thing: some.thing
... which is not what I want. How can I escape any periods (.) when using dot notation with omegaconf.OmegaConf.from_cli() ?
Based on the comment here, I think you could do something like:
python my_script.py foo[blah.bar]=blah.bar foo[another.thing]=some.thing
But I've never used omegaconf, so please don't beat me up for guessing :)
This is not supported.
You can file a feature request but it's not going to be high pri. I suggest that you use a different separator in your keys.
I am working on a project in which I am likely to be writing a lot of code of the form:
defmodule Kind
defstruct [name1, name2, name3]
#type t :: %Kind{name1: integer(), name2: integer(), name3: binary()}
def unpack(input) do
with <<name1::integer-8>> <- Enum.take(input, 1),
<<name2::integer-little-32>> <- Enum.take(input, 4),
<<name3::binary-10>> <- Enum.take(input, 10),
do: %Kind{name1: name1, name2: name2, name3: name3>>
end
end
(for arbitrary sets of input names and types, input being a binary stream producing one byte at a time)
It would be very useful to be able to handle this in a macro, so that I could simply write (for example) use Unpack quote([{name1, integer-8}, {name2, integer-little-32}, {name3, binary-10}]) and automatically generate the necessary struct, typedef, and unpacking function, for arbitrary named fields of fixed sizes. Could even expand it, add a third field in the tuples to pass a function to handle variably-sized types. Unfortunately, when I try to do a simpler version of that (only taking one sized field, and only matching 1 to it):
defmodule Unpack do
defmacro testmacro({name, kind}) do
quote do
<<unquote(name)::unqote(kind)>> = 1
end
end
end
The system tells me it's got invalid arguments for quote/1. I assume this is because the "types" used in bitstring pattern-matching are a special form, as are bitstring literals in general, and those particular items are not used anywhere else.
So, how do I get around that? I've got more than a dozen kinds of packed struct to unpack, each with between five and twenty different fields. If I don't do this I'll probably resort to Vim macros to at least save my hands... but that won't really help with having large amounts of extremely repetitive code to maintain.
Two things: you have a typo in unquote and the RHS must be a binary so that the pattern matches. With those changes, your code works for me:
defmodule Unpack do
defmacro unpack({name, kind}) do
quote do
<<unquote(name)::unquote(kind)>> = "a"
end
end
end
defmodule Main do
import Unpack
def main do
unpack({foo, integer-8})
IO.inspect foo
end
end
Main.main
Output:
97
How does one refer to the last argument in a given list of arguments in an m4 macro? I have a requirement to pull the last argument and generate macro expansion based on that.
This is not particularly elegant, but it works:
define(`last',`ifelse(`$#',`0',`',`$#',`1',`$1',`last(shift($#))')')dnl
last(foo,bar,baz)
# more elegant solution:
changequote([,])
define([LEN], [$#])
define([LAST], [pushdef([$0], $LEN($#))$0($#)[]popdef([$0])])
define([LAST_BUT_ONE], [pushdef([$0], $decr(LEN($#)))$0($#)[]popdef([$0])])
LAST(foo, bar, baz)
LAST_BUT_ONE(foo, bar, baz)
I want to extract a function foo in Coq to an OCaml file. Because my real function have to use the Recursive Extraction, when I run a program it output the extracted OCaml code on the cmd. But I would like to output it to a file, for example: foo.ml
Recursive Extraction foo.
When I tried:
Recursive Extraction "foo.ml" foo.
or Recursive Extraction foo "foo.ml"
I got an error: Syntax error: "." expected after [vernac:command] (in [vernac_aux]).
My question is: Am I able to extract the function foo to a file by using the Recursive Extraction syntax? Thank you for your help.
According to the manual (http://coq.inria.fr/distrib/V8.4/refman/Reference-Manual027.html), Extraction "foo.ml" foo will extract foo and recursively all its dependencies into foo.ml, i.e. you don't need Recursive in that case, it is only used for extraction on stdout.