More wip stuff

This commit is contained in:
IQuant 2024-11-24 20:47:58 +03:00
parent a830e0f33c
commit c7b389a389
4 changed files with 7660 additions and 18 deletions

View file

@ -41,8 +41,37 @@ impl Typ {
enum Typ2 { enum Typ2 {
#[serde(rename = "int")] #[serde(rename = "int")]
Int, Int,
#[serde(other)] #[serde(rename = "number")]
Other, Number,
#[serde(rename = "string")]
String,
#[serde(rename = "bool")]
Bool,
#[serde(rename = "entity_id")]
EntityId,
#[serde(rename = "component_id")]
ComponentId,
#[serde(rename = "obj")]
Obj,
#[serde(rename = "color")]
Color,
// #[serde(other)]
// Other,
}
impl Typ2 {
fn as_rust_type(&self) -> proc_macro2::TokenStream {
match self {
Typ2::Int => quote! {i32},
Typ2::Number => quote! {f64},
Typ2::String => quote! {String},
Typ2::Bool => quote! {bool},
Typ2::EntityId => quote! {EntityID},
Typ2::ComponentId => quote!(ComponentID),
Typ2::Obj => quote! {Obj},
Typ2::Color => quote!(Color),
}
}
} }
#[derive(Deserialize)] #[derive(Deserialize)]
@ -103,6 +132,7 @@ fn generate_code_for_component(com: Component) -> proc_macro2::TokenStream {
Some(quote! { Some(quote! {
#[doc = #field_doc] #[doc = #field_doc]
fn #field_name(self) -> #field_type { todo!() } fn #field_name(self) -> #field_type { todo!() }
#[doc = #field_doc]
fn #set_method_name(self, value: #field_type) { todo!() } fn #set_method_name(self, value: #field_type) { todo!() }
}) })
} }
@ -122,8 +152,19 @@ fn generate_code_for_component(com: Component) -> proc_macro2::TokenStream {
fn generate_code_for_api_fn(api_fn: ApiFn) -> proc_macro2::TokenStream { fn generate_code_for_api_fn(api_fn: ApiFn) -> proc_macro2::TokenStream {
let fn_name = format_ident!("{}", api_fn.fn_name.to_snek_case()); let fn_name = format_ident!("{}", api_fn.fn_name.to_snek_case());
let fn_doc = api_fn.desc;
let args = api_fn.args.iter().map(|arg| {
let arg_name = format_ident!("{}", arg.name);
let arg_type = arg.typ.as_rust_type();
quote! { quote! {
pub(crate) fn #fn_name() { #arg_name: #arg_type
}
});
quote! {
#[doc = #fn_doc]
pub(crate) fn #fn_name(#(#args,)*) {
} }
} }

File diff suppressed because one or more lines are too long

View file

@ -4,7 +4,20 @@ pub(crate) mod ntypes;
pub(crate) mod pixel; pub(crate) mod pixel;
mod api { mod api {
struct EntityID(u32);
struct ComponentID(u32);
struct Obj(usize);
struct Color(u32);
noita_api_macro::generate_components!(); noita_api_macro::generate_components!();
mod raw {
use super::{Color, ComponentID, EntityID, Obj};
noita_api_macro::generate_api!();
}
} }
pub(crate) struct ParticleWorldState { pub(crate) struct ParticleWorldState {

View file

@ -8,15 +8,36 @@ lines_iter = iter(lines)
parsed = [] parsed = []
def maybe_map_types(name, typ):
if name == "entity_id":
typ = "entity_id"
if name == "component_id":
typ = "component_id"
if typ == "float":
typ = "number"
if typ == "uint":
typ = "color"
if typ == "uint32":
typ = "color"
return typ
def parse_arg(arg_s): def parse_arg(arg_s):
if "|" in arg_s: if "|" in arg_s:
raise ValueError("multiple argument types not supported") raise ValueError("multiple argument types not supported")
other, *default = arg_s.split(" = ", maxsplit=1) if "{" in arg_s:
raise ValueError("no table support for now")
if "multiple_types" in arg_s:
raise ValueError("no 'multiple_types' either")
other, *default = arg_s.split("=", maxsplit=1)
other = other.strip()
if default: if default:
default = default[0] default = default[0].strip()
else: else:
default = None default = None
name, typ = other.split(":", maxsplit=1) name, typ = other.split(":", maxsplit=1)
typ = maybe_map_types(name, typ)
return { return {
"name": name, "name": name,
"typ": typ, "typ": typ,
@ -34,14 +55,15 @@ def parse_ret(ret_s):
raise ValueError("multiple return types not supported") raise ValueError("multiple return types not supported")
if "{" in ret_s: if "{" in ret_s:
raise ValueError("tables in returns not supported") raise ValueError("tables in returns not supported")
if "multiple_types" in ret_s:
raise ValueError("no 'multiple_types' either")
typ = other typ = ret_s
name = None name = None
if ":" in other: if ":" in ret_s:
name, typ = other.split(":", maxsplit=1) name, typ = ret_s.split(":", maxsplit=1)
if name == "entity_id": typ = maybe_map_types(name, typ)
typ = "entity_id"
return { return {
"name": name, "name": name,
@ -51,9 +73,11 @@ def parse_ret(ret_s):
ignore = { ignore = {
"PhysicsApplyForceOnArea",
"GetRandomActionWithType",
} }
skipped = 0 skipped = 0
deprecated = 0
# 2 lazy 2 parse xml properly # 2 lazy 2 parse xml properly
try: try:
@ -73,17 +97,28 @@ try:
print(f"Skipping {fn_name}: {e}") print(f"Skipping {fn_name}: {e}")
continue continue
ret = ret_line.removeprefix('<th><span class="field_name">').removesuffix('</span></th></th>').strip()
rets = ret_line.removeprefix('<th><span class="field_name">').removesuffix('</span></th></th>').strip()
desc = desc_line.removeprefix('<th><span class="description">').removesuffix('</span></th></th>').strip().replace("</br>", "\n")
if "Debugish" in rets:
rets, desc = rets.split(" (", maxsplit=1)
desc = desc.removesuffix(")")
rets = rets.split(", ")
try: try:
ret = parse_ret(ret) rets = [parse_ret(ret) for ret in rets if ret]
except ValueError as e: except ValueError as e:
print(f"Skipping {fn_name}: {e}") print(f"Skipping {fn_name}: {e}")
skipped += 1 skipped += 1
continue continue
desc = desc_line.removeprefix('<th><span class="description">').removesuffix('</span></th></th>').strip().replace("</br>", "\n")
if not desc: if not desc:
desc = "Nolla forgot to include a description :(" desc = "Nolla forgot to include a description :("
if "Deprecated" in desc_line:
deprecated += 1
print(f"Skipping {fn_name}: deprecated")
continue
#print(fn_line, ret_line, desc_line) #print(fn_line, ret_line, desc_line)
if fn_name not in ignore: if fn_name not in ignore:
@ -92,11 +127,15 @@ try:
"fn_name": fn_name, "fn_name": fn_name,
"args": args, "args": args,
"desc": desc, "desc": desc,
"rets": rets
}) })
else:
skipped += 1
except StopIteration: except StopIteration:
pass pass
print("Total skipped:", skipped) print("Total skipped:", skipped, deprecated)
json.dump(parsed, open("ewext/noita_api_macro/src/lua_api.json", "w"), indent=None) print("Total parsed:", len(parsed))
json.dump(parsed, open("ewext/noita_api_macro/src/lua_api.json", "w"), indent=2)