Browse Source

AP_Scripting: support true aliases

apm_2208
Iampete1 3 years ago committed by Andrew Tridgell
parent
commit
6e3cb7efdc
  1. 2
      libraries/AP_Scripting/generator/description/bindings.desc
  2. 167
      libraries/AP_Scripting/generator/src/main.c

2
libraries/AP_Scripting/generator/description/bindings.desc

@ -29,7 +29,7 @@ singleton AP_AHRS method get_roll float
singleton AP_AHRS method get_pitch float singleton AP_AHRS method get_pitch float
singleton AP_AHRS method get_yaw float singleton AP_AHRS method get_yaw float
singleton AP_AHRS method get_location boolean Location'Null singleton AP_AHRS method get_location boolean Location'Null
singleton AP_AHRS method get_position boolean Location'Null singleton AP_AHRS method get_location alias get_position
singleton AP_AHRS method get_home Location singleton AP_AHRS method get_home Location
singleton AP_AHRS method get_gyro Vector3f singleton AP_AHRS method get_gyro Vector3f
singleton AP_AHRS method get_accel Vector3f singleton AP_AHRS method get_accel Vector3f

167
libraries/AP_Scripting/generator/src/main.c

@ -7,6 +7,7 @@
#include <unistd.h> #include <unistd.h>
#include <getopt.h> #include <getopt.h>
char keyword_alias[] = "alias";
char keyword_rename[] = "rename"; char keyword_rename[] = "rename";
char keyword_ap_object[] = "ap_object"; char keyword_ap_object[] = "ap_object";
char keyword_comment[] = "--"; char keyword_comment[] = "--";
@ -55,6 +56,7 @@ enum error_codes {
ERROR_GENERAL = 6, // general error ERROR_GENERAL = 6, // general error
ERROR_SINGLETON = 7, // singletons ERROR_SINGLETON = 7, // singletons
ERROR_DEPENDS = 8, // dependencies ERROR_DEPENDS = 8, // dependencies
ERROR_DOCS = 9, // Documentation
}; };
struct header { struct header {
@ -343,6 +345,13 @@ struct method {
uint32_t flags; // filled out with TYPE_FLAGS uint32_t flags; // filled out with TYPE_FLAGS
}; };
struct method_alias {
struct method_alias *next;
char *name;
char *alias;
int line;
};
struct userdata_field { struct userdata_field {
struct userdata_field * next; struct userdata_field * next;
char * name; char * name;
@ -373,6 +382,7 @@ struct userdata {
char *rename; // (optional) used for scripting access char *rename; // (optional) used for scripting access
struct userdata_field *fields; struct userdata_field *fields;
struct method *methods; struct method *methods;
struct method_alias *method_aliases;
struct userdata_enum *enums; struct userdata_enum *enums;
enum userdata_type ud_type; enum userdata_type ud_type;
uint32_t operations; // bitset of enum operation_types uint32_t operations; // bitset of enum operation_types
@ -700,8 +710,9 @@ void handle_userdata_field(struct userdata *data) {
field->access_flags = parse_access_flags(&(field->type)); field->access_flags = parse_access_flags(&(field->type));
} }
void handle_method(char *parent_name, struct method **methods) { void handle_method(struct userdata *node) {
trace(TRACE_USERDATA, "Adding a method"); trace(TRACE_USERDATA, "Adding a method");
char * parent_name = node->name;
// find the field name // find the field name
char * name = next_token(); char * name = next_token();
@ -709,24 +720,52 @@ void handle_method(char *parent_name, struct method **methods) {
error(ERROR_USERDATA, "Missing method name for %s", parent_name); error(ERROR_USERDATA, "Missing method name for %s", parent_name);
} }
struct method * method = *methods; struct method * method = node->methods;
while (method != NULL && strcmp(method->name, name)) { while (method != NULL && strcmp(method->name, name)) {
method = method-> next; method = method-> next;
} }
if (method != NULL) { if (method != NULL) {
char *token = next_token(); char *token = next_token();
if (strcmp(token, keyword_rename) != 0) { if (strcmp(token, keyword_rename) == 0) {
error(ERROR_USERDATA, "Method %s already exists for %s (declared on %d)", name, parent_name, method->line);
}
char *rename = next_token(); char *rename = next_token();
string_copy(&(method->rename), rename); string_copy(&(method->rename), rename);
return; return;
} else if (strcmp(token, keyword_alias) == 0) {
char *alias_name = next_token();
struct method * method = node->methods;
while (method != NULL && strcmp(method->name, alias_name)) {
method = method-> next;
}
if (method != NULL) {
error(ERROR_USERDATA, "Method %s already exists for %s (declared on %d) cannot alias to %s", alias_name, parent_name, method->line, name);
}
struct method_alias *alias = allocate(sizeof(struct method_alias));
string_copy(&(alias->name), name);
string_copy(&(alias->alias), alias_name);
alias->line = state.line_num;
alias->next = node->method_aliases;
node->method_aliases = alias;
return;
}
error(ERROR_USERDATA, "Method %s already exists for %s (declared on %d)", name, parent_name, method->line);
}
struct method_alias * alias = node->method_aliases;
while (alias != NULL && strcmp(alias->alias, name)) {
alias = alias-> next;
}
if (alias != NULL) {
error(ERROR_USERDATA, "alias %s already exists for %s (declared on %d)", name, alias->name, alias->line);
} }
trace(TRACE_USERDATA, "Adding method %s", name); trace(TRACE_USERDATA, "Adding method %s", name);
method = allocate(sizeof(struct method)); method = allocate(sizeof(struct method));
method->next = *methods; method->next = node->methods;
*methods = method; node->methods = method;
string_copy(&(method->name), name); string_copy(&(method->name), name);
sanatize_name(&(method->sanatized_name), name); sanatize_name(&(method->sanatized_name), name);
method->line = state.line_num; method->line = state.line_num;
@ -830,7 +869,7 @@ void handle_userdata(void) {
node->next = parsed_userdata; node->next = parsed_userdata;
parsed_userdata = node; parsed_userdata = node;
} else { } else {
trace(TRACE_USERDATA, "Found exsisting userdata for %s", name); trace(TRACE_USERDATA, "Found existing userdata for %s", name);
} }
// read type // read type
@ -845,7 +884,7 @@ void handle_userdata(void) {
} else if (strcmp(type, keyword_operator) == 0) { } else if (strcmp(type, keyword_operator) == 0) {
handle_operator(node); handle_operator(node);
} else if (strcmp(type, keyword_method) == 0) { } else if (strcmp(type, keyword_method) == 0) {
handle_method(node->name, &(node->methods)); handle_method(node);
} else if (strcmp(type, keyword_enum) == 0) { } else if (strcmp(type, keyword_enum) == 0) {
handle_userdata_enum(node); handle_userdata_enum(node);
} else if (strcmp(type, keyword_rename) == 0) { } else if (strcmp(type, keyword_rename) == 0) {
@ -922,7 +961,7 @@ void handle_singleton(void) {
} else if (strcmp(type, keyword_semaphore_pointer) == 0) { } else if (strcmp(type, keyword_semaphore_pointer) == 0) {
node->flags |= UD_FLAG_SCHEDULER_SEMAPHORE; node->flags |= UD_FLAG_SCHEDULER_SEMAPHORE;
} else if (strcmp(type, keyword_method) == 0) { } else if (strcmp(type, keyword_method) == 0) {
handle_method(node->name, &(node->methods)); handle_method(node);
} else if (strcmp(type, keyword_enum) == 0) { } else if (strcmp(type, keyword_enum) == 0) {
handle_userdata_enum(node); handle_userdata_enum(node);
} else if (strcmp(type, keyword_depends) == 0) { } else if (strcmp(type, keyword_depends) == 0) {
@ -998,7 +1037,7 @@ void handle_ap_object(void) {
} else if (strcmp(type, keyword_semaphore_pointer) == 0) { } else if (strcmp(type, keyword_semaphore_pointer) == 0) {
node->flags |= UD_FLAG_SEMAPHORE_POINTER; node->flags |= UD_FLAG_SEMAPHORE_POINTER;
} else if (strcmp(type, keyword_method) == 0) { } else if (strcmp(type, keyword_method) == 0) {
handle_method(node->name, &(node->methods)); handle_method(node);
} else if (strcmp(type, keyword_depends) == 0) { } else if (strcmp(type, keyword_depends) == 0) {
if (node->dependency != NULL) { if (node->dependency != NULL) {
error(ERROR_SINGLETON, "AP_Objects only support a single depends"); error(ERROR_SINGLETON, "AP_Objects only support a single depends");
@ -2025,6 +2064,12 @@ void emit_index(struct userdata *head) {
field = field->next; field = field->next;
} }
struct method_alias *alias = node->method_aliases;
while(alias) {
fprintf(source, " {\"%s\", %s_%s},\n", alias->alias, node->sanatized_name, alias->name);
alias = alias->next;
}
fprintf(source, "};\n\n"); fprintf(source, "};\n\n");
if (node->operations) { if (node->operations) {
@ -2269,6 +2314,53 @@ void emit_docs_type(struct type type, const char *prefix, const char *suffix) {
} }
} }
void emit_docs_method(const char *name, const char *method_name, struct method *method) {
fprintf(docs, "-- desc\n");
struct argument *arg = method->arguments;
int count = 1;
// input arguments
while (arg != NULL) {
if ((arg->type.type != TYPE_LITERAL) && (arg->type.flags & (TYPE_FLAGS_NULLABLE | TYPE_FLAGS_REFERNCE)) == 0) {
char *param_name = (char *)allocate(20);
sprintf(param_name, "---@param param%i", count);
emit_docs_type(arg->type, param_name, "\n");
free(param_name);
count++;
}
arg = arg->next;
}
// return type
if ((method->flags & TYPE_FLAGS_NULLABLE) == 0) {
emit_docs_type(method->return_type, "---@return", "\n");
}
arg = method->arguments;
// nulable and refences returns
while (arg != NULL) {
if ((arg->type.type != TYPE_LITERAL) && (arg->type.flags & (TYPE_FLAGS_NULLABLE | TYPE_FLAGS_REFERNCE))) {
if (arg->type.flags & TYPE_FLAGS_NULLABLE) {
emit_docs_type(arg->type, "---@return", "|nil\n");
} else {
emit_docs_type(arg->type, "---@return", "\n");
}
}
arg = arg->next;
}
// function name
fprintf(docs, "function %s:%s(", name, method_name);
for (int i = 1; i < count; ++i) {
fprintf(docs, "param%i", i);
if (i < count-1) {
fprintf(docs, ", ");
}
}
fprintf(docs, ") end\n\n");
}
void emit_docs(struct userdata *node, int is_userdata, int emit_creation) { void emit_docs(struct userdata *node, int is_userdata, int emit_creation) {
while(node) { while(node) {
char *name = (char *)allocate(strlen(node->rename ? node->rename : node->sanatized_name) + 5); char *name = (char *)allocate(strlen(node->rename ? node->rename : node->sanatized_name) + 5);
@ -2344,51 +2436,28 @@ void emit_docs(struct userdata *node, int is_userdata, int emit_creation) {
// methods // methods
struct method *method = node->methods; struct method *method = node->methods;
while(method) { while(method) {
fprintf(docs, "-- desc\n"); emit_docs_method(name, method->rename ? method->rename : method->name, method);
struct argument *arg = method->arguments;
int count = 1;
// input arguments
while (arg != NULL) {
if ((arg->type.type != TYPE_LITERAL) && (arg->type.flags & (TYPE_FLAGS_NULLABLE | TYPE_FLAGS_REFERNCE)) == 0) {
char *param_name = (char *)allocate(20);
sprintf(param_name, "---@param param%i", count);
emit_docs_type(arg->type, param_name, "\n");
free(param_name);
count++;
}
arg = arg->next;
}
// return type method = method->next;
if ((method->flags & TYPE_FLAGS_NULLABLE) == 0) {
emit_docs_type(method->return_type, "---@return", "\n");
} }
arg = method->arguments; // aliases
// nulable and refences returns struct method_alias *alias = node->method_aliases;
while (arg != NULL) { while(alias) {
if ((arg->type.type != TYPE_LITERAL) && (arg->type.flags & (TYPE_FLAGS_NULLABLE | TYPE_FLAGS_REFERNCE))) { // find the method this is a alias of
if (arg->type.flags & TYPE_FLAGS_NULLABLE) { struct method * method = node->methods;
emit_docs_type(arg->type, "---@return", "|nil\n"); while (method != NULL && strcmp(method->name, alias->name)) {
} else { method = method-> next;
emit_docs_type(arg->type, "---@return", "\n");
}
} }
arg = arg->next; if (method == NULL) {
error(ERROR_DOCS, "Could not fine Method %s to alias to %s", alias->name, alias->alias);
} }
// function name emit_docs_method(name, alias->alias, method);
fprintf(docs, "function %s:%s(", name, method->rename ? method->rename : method->name);
for (int i = 1; i < count; ++i) { alias = alias->next;
fprintf(docs, "param%i", i);
if (i < count-1) {
fprintf(docs, ", ");
}
}
fprintf(docs, ") end\n\n");
method = method->next;
} }
fprintf(docs, "\n"); fprintf(docs, "\n");
free(name); free(name);
node = node->next; node = node->next;

Loading…
Cancel
Save