mirror of
https://codeberg.org/noisytoot/notnotdnethack.git
synced 2025-02-18 20:39:48 +00:00
Compiles without warnings. This includes the new Fire/Frost Brand base type rules from ndnh, which differ from both the old ndnh rules, the old and new dnh rules, and the old nndnh rules: crow quills are banned, but diskoses and isamuseis are allowed. I don't think this makes sense and I'll probably change it later, but I'm not sure how exactly yet.
148 lines
4.9 KiB
Python
Executable file
148 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 = 30
|
|
from math import log2
|
|
from math import ceil
|
|
EXPANDO = ceil(log2(MAXARG-MAXOUT))
|
|
EXPANDMAX = 2**EXPANDO
|
|
|
|
import os
|
|
|
|
# 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("\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()
|