aboutsummaryrefslogtreecommitdiff
path: root/source/20-codegen-compiler/CodegenDecl.hpp
blob: eacd2541f19c6de8e25953caff28f37a7d66e25b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#pragma once

#include "CodegenOutput.hpp"

#include <string>
#include <vector>

// TODO replace std::string name with std::string_view into the token storage?

struct SourceFile {
	std::string filename;
	CodegenOutput preHeaderOutput;
	CodegenOutput postHeaderOutput;
	CodegenOutput postSourceOutput;
	CodegenOutput tuOutput; // "tu" = Translation Unit, produces a separately compiled .cpp file
	bool header = false;
	/// Whether this file is being reprocessed in this invocation of codegen.exe or not.
	bool reprocessing = false;
};

struct DeclNamespace {
	// NOTE: namespace doesn't have a source file field, because the same namespace can be "reopened" in multipled files

	DeclNamespace* container = nullptr;
	std::string name;
	std::string_view fullname; // View into storage map key
};

struct DeclStruct;
struct DeclMemberVariable {
	DeclStruct* containerStruct = nullptr;
	std::string name;
	std::string type;
	std::string getterName;
	std::string setterName;
	bool isGetterGenerated = false;
	bool isSetterGenerated = false;
};
struct DeclMemberFunction {
	DeclStruct* containerStruct = nullptr;
	// TODO
};

// Structs or classes
struct DeclStruct {
	SourceFile* sourceFile = nullptr;
	DeclNamespace* container = nullptr;
	std::vector<const DeclStruct*> baseClasses;
	std::vector<DeclMemberVariable> memberVariables;
	std::vector<DeclMemberVariable> generatedVariables;
	std::vector<DeclMemberFunction> memberFunctions;
	std::vector<DeclMemberFunction> generatedFunctions;
	std::string name;
	mutable std::string mangledName;
	std::string_view fullname;

	// Scanned generation options
	bool generating : 1 = false;
	bool generatingInheritanceHiearchy : 1 = false;

	const std::string& GetMangledName() const;
};

enum EnumUnderlyingType {
	EUT_Int8,
	EUT_Int16,
	EUT_Int32,
	EUT_Int64,
	EUT_Uint8,
	EUT_Uint16,
	EUT_Uint32,
	EUT_Uint64,
	EUT_COUNT,
};

enum EnumValuePattern {
	// The numbers cover n..m with no gaps
	EVP_Continuous,
	// The numbers cover for i in n..m, 1 << i
	// e.g. [0] = 1 << 0,
	//      [1] = 1 << 1.
	//      [2] = 1 << 2. etc.
	EVP_Bits,
	// The numbesr don't have a particular pattern
	EVP_Random,
	EVP_COUNT,
};

struct DeclEnumElement {
	std::string name;
	// TODO support int64_t, etc. enum underlying types
	uint64_t value;
};

struct DeclEnum {
	SourceFile* sourceFile = nullptr;
	DeclNamespace* container = nullptr;
	std::string name;
	mutable std::string mangledName;
	std::string_view fullname;
	std::vector<DeclEnumElement> elements;
	EnumUnderlyingType underlyingType;
	// Start with invalid value, calculate on demand
	mutable EnumValuePattern pattern = EVP_COUNT;

	// TODO replace this with a regex?
	std::string generateRemovingPrefix;
	std::string generatingAddingPrefix;
	// NOTE: this flag acts as a gate for every specific generating option, must be enabled for them to work
	bool generating : 1 = false;
	bool generateToString : 1 = false;
	bool generateFromString : 1 = false;
	// NOTE: see GenerateForEnum() for the exact heuristics
	bool generateExcludeUseHeuristics : 1 = false;

	const std::string& GetName() const { return name; }
	std::string_view GetFullName() const { return fullname; }
	const std::string& GetMangledName() const;

	std::string_view GetUnderlyingTypeName() const;

	EnumValuePattern CalcPattern() const;
	EnumValuePattern GetPattern() const;
};

struct DeclFunctionArgument {
	std::string type;
	std::string name;
};

struct DeclFunction {
	SourceFile* sourceFile = nullptr;
	DeclNamespace* container = nullptr;
	// Things like extern, static, etc. that gets written before the function return type
	std::string prefix;
	std::string name;
	std::string_view fullname;
	std::string returnType;
	std::vector<DeclFunctionArgument> arguments;
	std::string body;
};