mirror of
https://codeberg.org/noisytoot/notnotdnethack.git
synced 2024-11-21 16:55:06 +00:00
Ron Nazarov
efdb5b2dc6
clang -std=c2x still doesn't work because clang is stricter and doesn't allow K&R-style declarations with -std=c2x. Also fix a few bugs/clang warnings discovered in the process.
145 lines
4.9 KiB
Python
Executable file
145 lines
4.9 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: MIT
|
|
# Based on https://gist.github.com/NeroOneTrueKing/384ce9faa3374f8d0b2ebf1ccc0ed222
|
|
|
|
# Permission is hereby granted, free of charge, to any person obtaining
|
|
# a copy of this software and associated documentation files (the
|
|
# "Software"), to deal in the Software without restriction, including
|
|
# without limitation the rights to use, copy, modify, merge, publish,
|
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
# permit persons to whom the Software is furnished to do so, subject to
|
|
# the following conditions:
|
|
|
|
# The above copyright notice and this permission notice shall be
|
|
# included in all copies or substantial portions of the Software.
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
# arguments
|
|
import sys
|
|
FILENAME = sys.argv[1] if 1 < len(sys.argv) else "include/macromagic.h"
|
|
README = sys.argv[2] if 2 < len(sys.argv) else "doc/macromagic.txt"
|
|
|
|
# constants
|
|
MAXARG = 59
|
|
MAXOUT = 29
|
|
from math import log2
|
|
from math import ceil
|
|
EXPANDO = ceil(log2(MAXARG-MAXOUT))
|
|
EXPANDMAX = 2**EXPANDO
|
|
|
|
# helper funcs
|
|
def strn(n):
|
|
return str(n//10) + str(n%10)
|
|
|
|
def largs(n):
|
|
s = ""
|
|
for i in range(1, n+1):
|
|
s = s + "_arg" + strn(i) + ', '
|
|
return s
|
|
|
|
f = open(FILENAME, 'w')
|
|
|
|
f.write("#ifndef MACROMAGIC_H\n")
|
|
f.write("#define MACROMAGIC_H\n")
|
|
|
|
f.write("//This file generated by python script. Do not edit.\n\n")
|
|
|
|
with open(README, 'r') as g:
|
|
f.write(g.read())
|
|
|
|
f.write("\n\n// O(1) macros\n")
|
|
# write O(1) macros
|
|
f.write("#define _EMPTY(...)\n")
|
|
f.write("#define _DEFER(...) __VA_ARGS__ _EMPTY()\n")
|
|
f.write("#define _EXPAND01(...) __VA_ARGS__\n")
|
|
for n in range(0, EXPANDO):
|
|
f.write("#define _EXPAND" + strn(2**(n+1)) + "(...) _EXPAND" + strn(2**n) + "(_EXPAND" + strn(2**n) + "(__VA_ARGS__))\n")
|
|
|
|
f.write("#define _DEPARENC(X) _DEPAREN(X),\n")
|
|
f.write("#define _DEPAREN(X) _ESC(_APEE X)\n")
|
|
f.write("#define _APEE(...) _APEE __VA_ARGS__\n")
|
|
f.write("#define _ESC(...) _ESC_(__VA_ARGS__)\n")
|
|
f.write("#define _ESC_(...) _ESC ## __VA_ARGS__\n")
|
|
f.write("#define _ESC_APEE\n")
|
|
|
|
f.write("\n\n// O(n) macros\n")
|
|
# write O(n) macros
|
|
f.write("#define _GET_NTH_ARG(\\\n")
|
|
for row in range(0, MAXARG//10+1):
|
|
f.write('\t')
|
|
for n in range(0, 10):
|
|
f.write('_'+str(row)+str(n)+', ')
|
|
f.write('\\\n')
|
|
f.write("\tN, ...) N\n\n")
|
|
|
|
f.write("#define NARGS(...) _GET_NTH_ARG(dummy __VA_OPT__(,) __VA_ARGS__,\\\n")
|
|
for row in range(MAXARG//10, -1, -1):
|
|
f.write('\t')
|
|
for n in range(9, -1, -1):
|
|
f.write(str(row)+str(n)+','*(n!=0 or row!=0)+' ')
|
|
f.write('\\\n')
|
|
f.write("\t)\n\n")
|
|
|
|
f.write("#define CALL_MACRO_X_FOR_EACH(x, ...)\\\n")
|
|
f.write("\t_GET_NTH_ARG(dummy __VA_OPT__(,) __VA_ARGS__,\\\n")
|
|
for row in range(MAXARG//10, -1, -1):
|
|
f.write('\t')
|
|
for n in range(9, -1, -1):
|
|
f.write('_fe_'+str(row)+str(n)+','*(n!=0 or row!=0)+' ')
|
|
f.write('\\\n')
|
|
f.write("\t)(x, ##__VA_ARGS__)\n\n")
|
|
|
|
f.write("#define _fe_00(_call, ...)\n")
|
|
f.write("#define _fe_01(_call, x)\t\t_call(x)\n")
|
|
for n in range(2, MAXARG+1):
|
|
f.write("#define _fe_" + strn(n) + "(_call, x, ...)\t_call(x) _fe_" + strn(n-1) + "(_call, __VA_ARGS__)\n")
|
|
f.write("\n")
|
|
|
|
for n in range(1, MAXOUT+1):
|
|
f.write("#define _OPEN_C" + strn(n) + "(...) __VA_ARGS__\n")
|
|
f.write("\n")
|
|
|
|
for n in range(1, MAXOUT+1):
|
|
f.write("#define SET" + strn(n) + "(" + largs(n) + "...) _EXPAND" + strn(EXPANDMAX) + "(DSET" + strn(n) + "(" + largs(n) +"## __VA_ARGS__, ))\n")
|
|
f.write("\n")
|
|
|
|
for n in range(1, MAXOUT+1):
|
|
f.write("#define DSET" + strn(n) + "(...) _SET" + strn(n) + "(__VA_ARGS__)\n")
|
|
f.write("\n")
|
|
|
|
for n in range(1, MAXOUT+1):
|
|
f.write("#define _SET" + strn(n) + "(" + largs(n) + "_nwarg, ...) SET" + strn(n) + "_DISC_ ## _nwarg (" + largs(n) +"_OPEN_ ## _nwarg, __VA_ARGS__)\n")
|
|
f.write("\n")
|
|
|
|
for n in range(1, MAXOUT+1):
|
|
f.write("#define _SET" + strn(n) + "_ID() _SET" + strn(n) + "\n")
|
|
f.write("\n")
|
|
|
|
for n in range(1, MAXOUT+1):
|
|
f.write("#define SET" + strn(n) + "_DISC_(" + largs(n) + "...) CALL_MACRO_X_FOR_EACH(_DEPARENC" + " ,"*(n>1) + largs(n-1)[:-2] + ") _DEPAREN(_arg"+strn(n)+")\n")
|
|
f.write("\n")
|
|
|
|
|
|
f.write("\n\n// O(n^2) macros\n")
|
|
# write O(n^2) macros
|
|
for n in range(1, MAXOUT+1):
|
|
for c in range(1, MAXOUT+1):
|
|
f.write("#define SET" + strn(n) + "_DISC_C" + strn(c) + "(...) SET" + strn(n) + "_REPL_C" + strn(c)+"\n")
|
|
f.write("\n")
|
|
|
|
for n in range(1, MAXOUT+1):
|
|
for c in range(1, n+1):
|
|
replargs = largs(n).replace(("_arg" + strn(c)), "_nwarg")
|
|
f.write("#define SET" + strn(n) + "_REPL_C" + strn(c) + "(" + largs(n) + "_nwarg, ...) _DEFER(_SET" + strn(n) + "_ID)()(" + replargs + "__VA_ARGS__)\n")
|
|
f.write("\n")
|
|
|
|
f.write("#endif /*MACROMAGIC_H*/\n")
|
|
|
|
f.close()
|