INITIAL COMMIT
This commit is contained in:
commit
da984bc702
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
codegen
|
||||||
|
main
|
31
.vscode/launch.json
vendored
Normal file
31
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Debug main",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceRoot}/main",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Set Disassembly Flavor to Intel",
|
||||||
|
"text": "-gdb-set disassembly-flavor intel",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
11
Makefile
Normal file
11
Makefile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
CC=clang
|
||||||
|
CFLAGS=-g -Wall -Werror -pedantic
|
||||||
|
META_OUT=./codegen
|
||||||
|
MAIN_OUT=main
|
||||||
|
|
||||||
|
main: codegen vec.c main.c
|
||||||
|
$(CC) $(CFLAGS) vec.c main.c -o $(MAIN_OUT)
|
||||||
|
|
||||||
|
codegen: codegen.c
|
||||||
|
$(CC) $(CFLAGS) codegen.c -o $(META_OUT)
|
||||||
|
$(META_OUT) vec
|
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# C Code Generation
|
||||||
|
|
||||||
|
Basic attempt at code generation for C. Generates 2D, 3D and 4D vector structs for int, float and double primitive types, as well as functions to print the values of the dimensions of each struct. It also create two macros `VEC(TYPE, COUNT)` which can be used to declare a variable of any of the defined vector types and `PRINT_VEC(TYPE, COUNT)` which can be used to call the respective print function for each vector type.
|
||||||
|
|
||||||
|
The `main.c` includes examples of using the macros.
|
||||||
|
|
||||||
|
`codegen.c` is where the code generation happens. The file includes 2 static arrays that control the code that will be generated. The `elem_names` array controls the largest vector that will be generated for each type. Currently, there are 4 element names defined, so the largest vector would be 4D.
|
||||||
|
|
||||||
|
The `elem_types` array defines the element base types for which vector structs will be generated.
|
13
aliases.h
Normal file
13
aliases.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef ALIASES_H
|
||||||
|
#define ALIASES_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define i32 int32_t
|
||||||
|
#define u8 uint8_t
|
||||||
|
#define u32 uint32_t
|
||||||
|
#define u64 uint64_t
|
||||||
|
#define f32 float
|
||||||
|
#define f64 double
|
||||||
|
|
||||||
|
#endif // !ALIASES_H
|
162
codegen.c
Normal file
162
codegen.c
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
#include "aliases.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
#define VEC_TYPEINFO(TYPE, SPEC) (vec_typeinfo){#TYPE, SPEC}
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
#define ARR_LEN(ARR) sizeof(ARR) / sizeof(ARR[0])
|
||||||
|
|
||||||
|
#define MIN_ELEM_COUNT 2
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *type_name;
|
||||||
|
const char *format_spec;
|
||||||
|
} vec_typeinfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
vec_typeinfo info;
|
||||||
|
u64 min;
|
||||||
|
u64 max;
|
||||||
|
} vec_type_decl;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
vec_typeinfo info;
|
||||||
|
u64 elem_count;
|
||||||
|
} vec_typedef;
|
||||||
|
|
||||||
|
void str_toupper(char *dst, const char *src, u64 len);
|
||||||
|
void create_vector_struct(const vec_typedef *vt, FILE *fp);
|
||||||
|
void decl_print_vector(const vec_typedef *vt, FILE *fp);
|
||||||
|
void def_print_vector(const vec_typedef *vt, FILE *fp);
|
||||||
|
|
||||||
|
static char elem_names[] = {'x', 'y', 'z', 'w'};
|
||||||
|
static vec_typeinfo elem_types[] = {
|
||||||
|
VEC_TYPEINFO(int, "%d"),
|
||||||
|
VEC_TYPEINFO(float, "%f"),
|
||||||
|
VEC_TYPEINFO(double, "%lf"),
|
||||||
|
};
|
||||||
|
|
||||||
|
i32 main(i32 argc, char *argv[]) {
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("Provide base file name\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 type_count = ARR_LEN(elem_types);
|
||||||
|
u64 max_elem_count = ARR_LEN(elem_names);
|
||||||
|
|
||||||
|
vec_type_decl vec_decls[type_count];
|
||||||
|
|
||||||
|
for (u32 i = 0; i < type_count; ++i) {
|
||||||
|
vec_decls[i] =
|
||||||
|
(vec_type_decl){elem_types[i], MIN_ELEM_COUNT, max_elem_count};
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *base_filename = argv[1];
|
||||||
|
|
||||||
|
char header_name[1024] = {0};
|
||||||
|
char source_name[1024] = {0};
|
||||||
|
|
||||||
|
sprintf(header_name, "%s.h", base_filename);
|
||||||
|
sprintf(source_name, "%s.c", base_filename);
|
||||||
|
|
||||||
|
// CREATE HEADER FILE
|
||||||
|
FILE *fp = fopen(header_name, "w");
|
||||||
|
if (!fp) {
|
||||||
|
printf("Failed to open file %s\n", header_name);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 len = strlen(base_filename);
|
||||||
|
char header_guard[len + 1];
|
||||||
|
memset((void *)header_guard, 0, len + 1);
|
||||||
|
str_toupper(header_guard, base_filename, len);
|
||||||
|
|
||||||
|
fprintf(fp, "#ifndef %s_H\n", header_guard);
|
||||||
|
fprintf(fp, "#define %s_H\n\n", header_guard);
|
||||||
|
|
||||||
|
fprintf(fp, "#include \"aliases.h\"\n");
|
||||||
|
fprintf(fp, "#include <stdint.h>\n");
|
||||||
|
fprintf(fp, "#include <stdio.h>\n\n");
|
||||||
|
|
||||||
|
fprintf(fp, "#define VEC(TYPE, COUNT) vec##COUNT##_##TYPE\n");
|
||||||
|
fprintf(fp, "#define PRINT_VEC(TYPE, COUNT) print_vec##COUNT##_##TYPE\n\n");
|
||||||
|
|
||||||
|
for (u32 i = 0; i < type_count; ++i) {
|
||||||
|
vec_type_decl *vec_decl = &(vec_decls[i]);
|
||||||
|
vec_typedef vt = {vec_decl->info};
|
||||||
|
|
||||||
|
for (u8 j = vec_decl->min; j <= vec_decl->max; ++j) {
|
||||||
|
vt.elem_count = j;
|
||||||
|
|
||||||
|
create_vector_struct(&vt, fp);
|
||||||
|
decl_print_vector(&vt, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "\n#endif // %s_H\n", header_guard);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
// CREATE SOURCE FILE
|
||||||
|
fp = fopen(source_name, "w");
|
||||||
|
if (!fp) {
|
||||||
|
printf("Failed to open file %s\n", source_name);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "#include \"%s\"\n\n", header_name);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < type_count; ++i) {
|
||||||
|
vec_type_decl *vec_decl = &(vec_decls[i]);
|
||||||
|
vec_typedef vt = {vec_decl->info};
|
||||||
|
|
||||||
|
for (u8 j = vec_decl->min; j <= vec_decl->max; ++j) {
|
||||||
|
vt.elem_count = j;
|
||||||
|
|
||||||
|
def_print_vector(&vt, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void str_toupper(char *dst, const char *src, u64 len) {
|
||||||
|
for (u32 i = 0; i < len; ++i) {
|
||||||
|
dst[i] = toupper(src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_vector_struct(const vec_typedef *vt, FILE *fp) {
|
||||||
|
fprintf(fp, "typedef struct {\n");
|
||||||
|
|
||||||
|
for (u8 i = 0; i < vt->elem_count; ++i) {
|
||||||
|
fprintf(fp, "\t%s %c;\n", vt->info.type_name, elem_names[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "} vec%zu_%s;\n", vt->elem_count, vt->info.type_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void decl_print_vector(const vec_typedef *vt, FILE *fp) {
|
||||||
|
fprintf(fp, "void print_vec%zu_%s(const vec%zu_%s *vec);\n\n", vt->elem_count,
|
||||||
|
vt->info.type_name, vt->elem_count, vt->info.type_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void def_print_vector(const vec_typedef *vt, FILE *fp) {
|
||||||
|
fprintf(fp, "void print_vec%zu_%s(const vec%zu_%s *vec) {\n", vt->elem_count,
|
||||||
|
vt->info.type_name, vt->elem_count, vt->info.type_name);
|
||||||
|
|
||||||
|
for (u8 i = 0; i < vt->elem_count; ++i) {
|
||||||
|
fprintf(fp, "\tprintf(\"%c: %s\t\", vec->%c);\n", elem_names[i],
|
||||||
|
vt->info.format_spec, elem_names[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "}\n\n");
|
||||||
|
}
|
20
main.c
Normal file
20
main.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "aliases.h"
|
||||||
|
#include "vec.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
i32 main(i32 argc, char *argv[]) {
|
||||||
|
VEC(int, 3) vec1 = {4, 10, 8};
|
||||||
|
PRINT_VEC(int, 3)(&vec1);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
VEC(float, 2) vec2 = {1.4f, 2.0f};
|
||||||
|
PRINT_VEC(float, 2)(&vec2);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
VEC(double, 4) vec3 = {2.3, 8.5, 9.2, 1.0};
|
||||||
|
PRINT_VEC(double, 4)(&vec3);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
56
vec.c
Normal file
56
vec.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include "vec.h"
|
||||||
|
|
||||||
|
void print_vec2_int(const vec2_int *vec) {
|
||||||
|
printf("x: %d ", vec->x);
|
||||||
|
printf("y: %d ", vec->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vec3_int(const vec3_int *vec) {
|
||||||
|
printf("x: %d ", vec->x);
|
||||||
|
printf("y: %d ", vec->y);
|
||||||
|
printf("z: %d ", vec->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vec4_int(const vec4_int *vec) {
|
||||||
|
printf("x: %d ", vec->x);
|
||||||
|
printf("y: %d ", vec->y);
|
||||||
|
printf("z: %d ", vec->z);
|
||||||
|
printf("w: %d ", vec->w);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vec2_float(const vec2_float *vec) {
|
||||||
|
printf("x: %f ", vec->x);
|
||||||
|
printf("y: %f ", vec->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vec3_float(const vec3_float *vec) {
|
||||||
|
printf("x: %f ", vec->x);
|
||||||
|
printf("y: %f ", vec->y);
|
||||||
|
printf("z: %f ", vec->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vec4_float(const vec4_float *vec) {
|
||||||
|
printf("x: %f ", vec->x);
|
||||||
|
printf("y: %f ", vec->y);
|
||||||
|
printf("z: %f ", vec->z);
|
||||||
|
printf("w: %f ", vec->w);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vec2_double(const vec2_double *vec) {
|
||||||
|
printf("x: %lf ", vec->x);
|
||||||
|
printf("y: %lf ", vec->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vec3_double(const vec3_double *vec) {
|
||||||
|
printf("x: %lf ", vec->x);
|
||||||
|
printf("y: %lf ", vec->y);
|
||||||
|
printf("z: %lf ", vec->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vec4_double(const vec4_double *vec) {
|
||||||
|
printf("x: %lf ", vec->x);
|
||||||
|
printf("y: %lf ", vec->y);
|
||||||
|
printf("z: %lf ", vec->z);
|
||||||
|
printf("w: %lf ", vec->w);
|
||||||
|
}
|
||||||
|
|
75
vec.h
Normal file
75
vec.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#ifndef VEC_H
|
||||||
|
#define VEC_H
|
||||||
|
|
||||||
|
#include "aliases.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define VEC(TYPE, COUNT) vec##COUNT##_##TYPE
|
||||||
|
#define PRINT_VEC(TYPE, COUNT) print_vec##COUNT##_##TYPE
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
} vec2_int;
|
||||||
|
void print_vec2_int(const vec2_int *vec);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
} vec3_int;
|
||||||
|
void print_vec3_int(const vec3_int *vec);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
int w;
|
||||||
|
} vec4_int;
|
||||||
|
void print_vec4_int(const vec4_int *vec);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
} vec2_float;
|
||||||
|
void print_vec2_float(const vec2_float *vec);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
} vec3_float;
|
||||||
|
void print_vec3_float(const vec3_float *vec);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float w;
|
||||||
|
} vec4_float;
|
||||||
|
void print_vec4_float(const vec4_float *vec);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
} vec2_double;
|
||||||
|
void print_vec2_double(const vec2_double *vec);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double z;
|
||||||
|
} vec3_double;
|
||||||
|
void print_vec3_double(const vec3_double *vec);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double z;
|
||||||
|
double w;
|
||||||
|
} vec4_double;
|
||||||
|
void print_vec4_double(const vec4_double *vec);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VEC_H
|
Loading…
Reference in New Issue
Block a user