#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#include <math.h>
#include "misc.h"
s8 *vec_array[] = {"x","y","z","u","v","w"};
void vector_normal_operator(s8 *operator_string, s8 *type, s32 size)
{
forI(i, size)
{
printf("internal v%i%s operator %s(v%i%s a,v%i%s b)\n", i+1, type, operator_string, i+1, type, i+1, type);
printf("{\n");
printf("\treturn v%i%s{", i+1, type);
for(s32 j = 0;; ++j)
{
printf("CAST(%s, a[%i] %s b[%i])", type, j, operator_string, j);
if(j + 1 > i) break;
printf(", ");
}
printf("};\n");
printf("}\n");
}
}
void vector_reference_operator(s8 *operator_string, s8 *type, s32 size)
{
forI(i, size)
{
printf("internal void operator %s(v%i%s& a, v%i%s b)\n", operator_string, i+1, type, i+1, type);
printf("{ a = a + b; }\n");
}
}
void vector_create(s8 *type, s8 *type_print, s32 size)
{
// structs
forI(i, size)
{
printf("union v%i%s{\n",i + 1, type);
printf("\tstruct{\n");
for(s32 j = 0; j < i+1; ++j)
{
printf("\t\t%s %s;\n", type, vec_array[j]);
}
printf("\t};\n");
printf("\t%s element_[%i];\n", type, i+1);
printf("\t%s& operator [](s32 i)", type);
printf("\t{\n");
printf("\t\treturn this->element_[i];\n");
printf("\t}\n");
printf("};\n");
}
// Operator Overloading
vector_normal_operator("+", type, size);
vector_normal_operator("-", type, size);
vector_normal_operator("*", type, size);
vector_normal_operator("/", type, size);
vector_reference_operator("+=", type, size);
vector_reference_operator("-=", type, size);
vector_reference_operator("*=", type, size);
vector_reference_operator("/=", type, size);
forI(i, size)
{
printf("internal v%i%s operator -(v%i%s a)\n", i+1, type, i+1, type);
printf("{\n");
printf("\treturn v%i%s{", i+1, type);
for(s32 j = 0;; ++j)
{
printf("CAST(%s, -a[%i])", type, j);
if(j + 1 > i) break;
printf(", ");
}
printf("};\n");
printf("}\n");
}
// va_print
forI(i, size)
{
printf("internal void va_print(v%i%s a)\n", i+1, type);
printf("{\n");
printf("\tprintf(\"v%i%s{", i+1, type);
for(s32 j = 0;; ++j)
{
printf("%s", type_print);
if(j + 1 > i) break;
printf(", ");
}
printf("}\"");
for(s32 j = 0;; ++j)
{
printf(", a[%i]",j);
if(j + 1 > i) break;
}
printf(");\n");
printf("}\n");
}
}
void vector_create_float_function(s8 *type, s32 size)
{
// v_length
forI(i, size)
{
printf("internal %s v_length(v%i%s a)\n", type, i+1, type);
printf("{\n");
printf("\treturn CAST(%s, sqrt(",type); // Verify: need cast to type??
for(s32 j = 0;; ++j)
{
printf("(a*a)[%i]", j);
if(j + 1 > i) break;
printf(" + ");
}
printf("));\n");
printf("}\n");
}
// v_angle
printf("internal %s v_angle(v2%s a)\n", type, type);
printf("{\n");
printf("\t%s Result = CAST(%s, atan2(a[0],a[1]));\n",type, type);
printf("\treturn Result >= 0 ? Result : Result + (%s)TAU;\n", type);
printf("}\n");
// v2type_new
printf("internal v2%s v2%s_new(%s angle, %s length)\n", type, type, type, type);
printf("{\n");
printf("\treturn v2%s{CAST(%s, cos(angle)) * length, CAST(%s, sin(angle)) * length};\n", type, type, type);
printf("}\n");
// v2_rotate
printf("internal v2%s v2_rotate(v2%s a, %s rotation)\n", type, type, type);
printf("{\n");
printf("\treturn v2%s{CAST(%s, a[0] * sin(rotation)), CAST(%s, a[1] * cos(rotation))};\n", type, type, type);
printf("}\n");
// v_normal
forI(i, size)
{
printf("internal v%i%s v_normal(v%i%s a)\n", i+1, type, i+1, type);
printf("{\n");
printf("\t%s l = v_length(a);\n", type);
printf("\treturn v%i%s{", i+1, type);
for(s32 j = 0;; ++j)
{
printf("a[%i] / l",j);
if(j + 1 > i) break;
printf(", ");
}
printf("};\n");
printf("}\n");
}
}
s32 main()
{
printf("/*Vector Library*/\n");
vector_create("s8", "%i", 6);
vector_create("s16", "%i", 6);
vector_create("s32", "%i", 6);
vector_create("s64", "%lli", 6);
vector_create("f32", "%g", 6);
vector_create_float_function("f32", 6);
vector_create("f64", "%g", 6);
vector_create_float_function("f64", 6);
return 0;
}
#define TOSTRING_(a) #a
#define TOSTRING(a) TOSTRING_(a)
#define CONCAT_(a,b) a##b
#define CONCAT(...) FOLD(CONCAT_, __VA_ARGS__)
#define CAST(Type, Value) ((Type)(Value))
#define CASTBIT(Type, Value) (*CAST(Type *, &(Value)))
#define forI(IndexName, LoopCount) \
for(u32 (IndexName) = 0; (IndexName) < (LoopCount); ++(IndexName))
#define forS(IndexName, String) \
for(u32 (IndexName) = 0; (String)[IndexName] != 0; ++(IndexName))
#define forS0(Name, String) \
for(u32 Name = 0; Name == 0 || (String)[Name-1]; Name++)
#define forW(IndexName) \
for(u32 (IndexName) = 0; ; ++(IndexName))
#define internal static
#define persist static
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef char s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef bool b8;
typedef float f32;
typedef double f64;
// Type Naughty List
#define int {---"Dont use int"---}
#define short {---"Dont use short"---}
#define char {---"Dont use char"---}
#define long {---"Dont use long"---}
#define float {---"Dont use float"---}
#define double {---"Dont use double"---}
#define unsigned {---"Dont use unsigned"---}
#define signed {---"Dont use signed"---}
#define size_t {---"Dont use size_t"---}
struct ShortString{
s8 element_[8];
s8& operator [](s32 i)
{
return element_[i];
}
};
#define TAU 6.28318530717958647