Skip to content

Commit 4ab19e5

Browse files
committed
POLYMORPHIC PIONTERS
1 parent ed5ff41 commit 4ab19e5

8 files changed

Lines changed: 8731 additions & 136 deletions

File tree

3

Lines changed: 3243 additions & 0 deletions
Large diffs are not rendered by default.

a.ll

Lines changed: 5294 additions & 73 deletions
Large diffs are not rendered by default.

compiler.cpp

Lines changed: 104 additions & 45 deletions
Large diffs are not rendered by default.

compiler.h

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,8 @@ class LLVMCompiler {
12081208
std::unordered_map<std::string, llvm::StructType*> structTypes;
12091209
std::unordered_map<std::string, llvm::StructType*> unionTypes;
12101210
std::unordered_map<std::string, llvm::StructType*> classTypes;
1211+
std::unordered_map<std::string, llvm::GlobalVariable*> vtables;
1212+
std::unordered_map<std::string, std::unordered_map<std::string, int>> vtableSlotIndex;
12111213
std::unordered_map<std::string, std::unordered_map<std::string, std::vector<llvm::Function*>>> classMethods;
12121214
llvm::Value* currentThis = nullptr;
12131215
std::string currentClassName = "";
@@ -1321,7 +1323,7 @@ class LLVMCompiler {
13211323
} else if (auto unaryOp = std::get_if<UnaryOpNode*>(&node)) {
13221324
std::string type = getExpressionType((*unaryOp)->node, strip);
13231325
if ((*unaryOp)->op_tok.type == TokenType::MUL) {
1324-
if (type.ends_with("*")) { type.pop_back(); }
1326+
if (type.ends_with("*") && strip) { type.pop_back(); }
13251327
}
13261328
return type;
13271329
} else if (auto binOp = std::get_if<BinOpNode*>(&node)) {
@@ -1541,6 +1543,7 @@ class LLVMCompiler {
15411543
return addr;
15421544
} else if (auto unary = std::get_if<UnaryOpNode*>(&node)) {
15431545
if ((*unary)->op_tok.type == TokenType::MUL) { return emitExpr((*unary)->node); }
1546+
if ((*unary)->op_tok.type == TokenType::AMPERSAND) { return emitLValue((*unary)->node); }
15441547
} else if (auto prop = std::get_if<PropertyAccessNode*>(&node)) {
15451548
return emitPropertyAddress(**prop);
15461549
} else if (auto call = std::get_if<CallNode*>(&node)) {
@@ -2130,6 +2133,24 @@ class LLVMCompiler {
21302133
}
21312134
return builder->CreateCall(method, reconciled, name + "_result");
21322135
}
2136+
std::string resolveVirtualTargetClass(const std::string& declaredClass,
2137+
const std::string& methodName,
2138+
size_t argCount) {
2139+
for (auto& m : userTypes[declaredClass].classMethods) {
2140+
if (m.name_tok.value == methodName && m.params.size() == argCount)
2141+
return declaredClass;
2142+
}
2143+
for (auto& [name, info] : userTypes) {
2144+
if (info.baseClassName == declaredClass) {
2145+
for (auto& m : info.classMethods) {
2146+
if (m.name_tok.value == methodName && m.params.size() == argCount)
2147+
return name;
2148+
}
2149+
}
2150+
}
2151+
return declaredClass;
2152+
}
2153+
21332154
llvm::Function* findMethodOverload(const std::string& className, const std::string& methodName, const std::vector<llvm::Value*>& args) {
21342155
std::string resolvedClassName = className;
21352156
if (className.find("::") == std::string::npos && !getCurrentNamespace().empty()) {
@@ -2220,6 +2241,38 @@ class LLVMCompiler {
22202241

22212242
return nullptr;
22222243
}
2244+
llvm::Value* emitVirtualOrDirectCall(
2245+
const std::string& ty,
2246+
const std::string& methodName,
2247+
llvm::Value* payload,
2248+
const std::vector<llvm::Value*>& args)
2249+
{
2250+
auto vtableIt = vtables.find(ty);
2251+
auto slotIt = vtableSlotIndex.find(ty);
2252+
if (vtableIt != vtables.end() && slotIt != vtableSlotIndex.end()) {
2253+
std::string mangledName = ty + "_" + methodName;
2254+
auto indexIt = slotIt->second.find(mangledName);
2255+
if (indexIt != slotIt->second.end()) {
2256+
int slotIndex = indexIt->second;
2257+
llvm::StructType* classTy = classTypes[ty];
2258+
llvm::Value* vptrField = builder->CreateStructGEP(classTy, payload, 0, "vptr_field");
2259+
llvm::Value* vptr = builder->CreateLoad(builder->getPtrTy(), vptrField, "vptr");
2260+
llvm::Value* fnPtrAddr = builder->CreateGEP(builder->getPtrTy(), vptr,
2261+
builder->getInt32(slotIndex), "vtable_slot");
2262+
llvm::Value* fnPtr = builder->CreateLoad(builder->getPtrTy(), fnPtrAddr, "fn_ptr");
2263+
2264+
llvm::Function* method = findMethodOverload(ty, methodName, args);
2265+
if (!method) return nullptr;
2266+
2267+
std::vector<llvm::Value*> allArgs = {payload};
2268+
allArgs.insert(allArgs.end(), args.begin(), args.end());
2269+
return builder->CreateCall(method->getFunctionType(), fnPtr, allArgs);
2270+
}
2271+
}
2272+
llvm::Function* method = findMethodOverload(ty, methodName, args);
2273+
if (!method) return nullptr;
2274+
return emitMethodCall(method, payload, args, methodName);
2275+
}
22232276
llvm::Function* generateSpecializedMethod(const std::string& className, size_t methodIdx, const std::vector<std::string>& concreteTypes,
22242277
const std::string& specializedName) {
22252278
llvm::Function* savedFunction = currentFunction;

compiler_run.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#if defined(_WIN32) || defined(_WIN64)
2121
#include <print>
2222
#endif
23-
const std::string ver = "x0.17.73";
23+
const std::string ver = "x0.17.75";
2424
#include <random>
2525
bool slow = false;
2626
void slow_print(const std::string& text, const std::string& color = "\033[0m", int min_delay_ms = 100, int max_delay_ms = 450) {

roadmap.md

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
- Array-initing pointers
21
- Concepts
32
```
43
concept X {
@@ -10,7 +9,6 @@ class Y {
109
Y proves X;
1110
```
1211
- Try/Catch
13-
- Polymorphic pointers. Class* = &Child
1412
- Generics (`class List<T, int S>`....., `class MultiNumbers<T(!int|double|float)>`, `class VaradicTypes<...Tys>`)
1513
- Operator[i] (subscript, eg `class[123]`), operator[](brace initialization, eg `Classname c = [1, 2, 3, 4]`), operator{:}(map initialization, e.g. `Classname c = {"true": 1, "false": 0};`)
1614
- Code block functions (`void myKey() code { code.eval }; int main() { myKey () { …. } }`)
@@ -77,19 +75,17 @@ void loop(void) code {
7775
- qconform (QC Formatter)
7876
- operator++/–/+=/-=//=/*=(combinational operators)
7977
TOP PRIORITY:
80-
1. Array-initing pointers.
81-
2. Polymorphic pointers.
82-
3. Generics.
83-
4. Self host the runtime.
84-
5. Try/Catch.
85-
6. Fancy operator overloads
86-
7. Token/ident/type/keyword/usertype direct type (parser refactor)
87-
8. Codeblocks.
88-
9. Concepts
89-
10. Modifier (x1.0.0)
90-
11. CQB.
91-
12. Other stuff
92-
13. Metadata
78+
1. Generics.
79+
2. Self host the runtime.
80+
3. Try/Catch.
81+
4. Fancy operator overloads
82+
5. Token/ident/type/keyword/usertype direct type (parser refactor)
83+
6. Codeblocks.
84+
7. Concepts
85+
8. Modifier (x1.0.0)
86+
9. CQB.
87+
10. Other stuff
88+
11. Metadata
9389
?likely? - likely marked
9490
?unlikely? - marked unlikely
9591
?inline? - pls inline >-<

test_vt.qc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class A {
2+
int add(int a) {
3+
return a + 2;
4+
}
5+
A() {
6+
}
7+
}
8+
class B : A {
9+
int add(int a, int b) {
10+
return a + b;
11+
}
12+
B() {
13+
}
14+
}
15+
int main() {
16+
A a = A();
17+
A* aClass = &a;
18+
qout("%i", aClass->add(123));
19+
B b = B();
20+
aClass = &b;
21+
qout("%i", aClass->add(123, 321));
22+
return 0;
23+
} // just need to handle the actusal method calls

version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
x0.17.73
1+
x0.17.75

0 commit comments

Comments
 (0)