Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/ast/ControlStatementNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Operand WhileNode::generateIR(CFG &graph, SymbolTable &st) {

graph.setCurrentBlock(headerBlock);
const auto &condName = cond->generateIR(graph, st);
auto *conditionBlock = graph.getCurrentBlock();
graph.addInstruction(new CondJumpTac(joinBlock->getName(), condName));
graph.addInstruction(new JumpTac(bodyBlock->getName()));

Expand All @@ -77,8 +78,8 @@ Operand WhileNode::generateIR(CFG &graph, SymbolTable &st) {
graph.getCurrentBlock()->setTrueBlock(headerBlock);
graph.addInstruction(new JumpTac(headerLabel));

headerBlock->setTrueBlock(bodyBlock);
headerBlock->setFalseBlock(joinBlock);
conditionBlock->setTrueBlock(bodyBlock);
conditionBlock->setFalseBlock(joinBlock);

graph.setCurrentBlock(joinBlock);

Expand Down
7 changes: 4 additions & 3 deletions src/ast/MethodCallNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Operand MethodCallNode::generateIR(CFG &graph, SymbolTable &st) {
}

const auto &methodType = method->getType();
object->generateIR(graph, st);
const auto receiver = object->generateIR(graph, st);

for (const auto &arg : exprList->children) {
const auto &argName = arg->generateIR(graph, st);
Expand All @@ -34,8 +34,9 @@ Operand MethodCallNode::generateIR(CFG &graph, SymbolTable &st) {
st.addVariable(methodType, name);

const auto &methodName = id->value;
const auto argCount = std::to_string(exprList->children.size());
const auto methodTarget = *caller_type + "." + methodName;
const auto argCount = static_cast<int>(exprList->children.size());
graph.addInstruction(
new MethodCallTac(name, methodName, *caller_type, argCount));
new MethodCallTac(name, receiver, methodTarget, argCount));
return name;
}
6 changes: 3 additions & 3 deletions src/ast/MethodCallWithoutArgumentsNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ Operand MethodCallWithoutArgumentsNode::generateIR(CFG &graph,
}

const auto &methodType = method->getType();
object->generateIR(graph, st);
const auto receiver = object->generateIR(graph, st);

const auto &name = graph.getTemporaryName();
st.addVariable(methodType, name);
const auto &methodName = id->value;
graph.addInstruction(
new MethodCallTac(name, methodName, *caller_type, "0"));
const auto methodTarget = *caller_type + "." + methodName;
graph.addInstruction(new MethodCallTac(name, receiver, methodTarget, 0));
return name;
}
1 change: 1 addition & 0 deletions src/bytecode/BytecodeMethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ void BytecodeMethod::print(std::ostream &os) const {
void BytecodeMethod::serialize(Serializer &serializer) const {
serializer.writeString(name);
serializer.writeStringVector(variables);
serializer.writeStringVector(fieldVariables);
serializer.writeInteger(blocks.size());
for (const auto &block : blocks) {
serializer.writeString(block.getName());
Expand Down
10 changes: 8 additions & 2 deletions src/bytecode/BytecodeMethod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ class BytecodeMethod {

std::string name;
std::vector<std::string> variables;
std::vector<std::string> fieldVariables;

public:
BytecodeMethod(const std::string &name_,
std::vector<std::string> variables_)
: name(name_), variables(std::move(variables_)) {};
std::vector<std::string> variables_,
std::vector<std::string> fieldVariables_)
: name(name_), variables(std::move(variables_)),
fieldVariables(std::move(fieldVariables_)) {};

bool operator==(const std::string &otherName) const {
return name == otherName;
Expand All @@ -32,6 +35,9 @@ class BytecodeMethod {
void print(std::ostream &os) const;

[[nodiscard]] const auto &getVariables() const { return variables; }
[[nodiscard]] const auto &getFieldVariables() const {
return fieldVariables;
}

void serialize(Serializer &serializer) const;
};
Expand Down
22 changes: 22 additions & 0 deletions src/bytecode/BytecodeMethodBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,28 @@ BytecodeMethodBlock &BytecodeMethodBlock::call(const std::string &method) {
new StringParameterInstruction(Opcode::CALL, method));
return *this;
}
BytecodeMethodBlock &
BytecodeMethodBlock::new_object(const std::string &className) {
addBytecodeInstruction(
new StringParameterInstruction(Opcode::NEW, className));
return *this;
}
BytecodeMethodBlock &BytecodeMethodBlock::new_array() {
addBytecodeInstruction(new StackParameterInstruction(Opcode::NEW_ARRAY));
return *this;
}
BytecodeMethodBlock &BytecodeMethodBlock::array_load() {
addBytecodeInstruction(new StackParameterInstruction(Opcode::ARRAY_LOAD));
return *this;
}
BytecodeMethodBlock &BytecodeMethodBlock::array_store() {
addBytecodeInstruction(new StackParameterInstruction(Opcode::ARRAY_STORE));
return *this;
}
BytecodeMethodBlock &BytecodeMethodBlock::array_length() {
addBytecodeInstruction(new StackParameterInstruction(Opcode::ARRAY_LENGTH));
return *this;
}

BytecodeMethodBlock &BytecodeMethodBlock::jump(const std::string &location) {
addBytecodeInstruction(
Expand Down
5 changes: 5 additions & 0 deletions src/bytecode/BytecodeMethodBlock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ class BytecodeMethodBlock {
BytecodeMethodBlock &write();

BytecodeMethodBlock &call(const std::string &method);
BytecodeMethodBlock &new_object(const std::string &className);
BytecodeMethodBlock &new_array();
BytecodeMethodBlock &array_load();
BytecodeMethodBlock &array_store();
BytecodeMethodBlock &array_length();

BytecodeMethodBlock &jump(const std::string &location);
BytecodeMethodBlock &cjump(const std::string &location);
Expand Down
6 changes: 4 additions & 2 deletions src/bytecode/BytecodeProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@

BytecodeMethod &
BytecodeProgram::addBytecodeMethod(const std::string &name,
std::vector<std::string> variables) {
methods.push_back(BytecodeMethod(name, std::move(variables)));
std::vector<std::string> variables,
std::vector<std::string> fieldVariables) {
methods.push_back(
BytecodeMethod(name, std::move(variables), std::move(fieldVariables)));
return methods.back();
}

Expand Down
3 changes: 2 additions & 1 deletion src/bytecode/BytecodeProgram.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ class BytecodeProgram {
public:
[[nodiscard]] BytecodeMethod &
addBytecodeMethod(const std::string &name,
std::vector<std::string> variables);
std::vector<std::string> variables,
std::vector<std::string> fieldVariables);

[[nodiscard]] BytecodeMethod &getBytecodeMethod(const std::string &name);

Expand Down
14 changes: 10 additions & 4 deletions src/bytecode/Opcode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@ enum Opcode : int8_t {
CALL = 15,
RET = 16,
PRINT = 17,
STOP = 18
STOP = 18,
NEW = 19,
NEW_ARRAY = 20,
ARRAY_LOAD = 21,
ARRAY_STORE = 22,
ARRAY_LENGTH = 23
};

const std::vector<std::string> mnemonics{
"ILOAD", "ICONST", "ISTORE", "IADD", "ISUB", "IMUL", "IDIV",
"ILT", "IGT", "IEQ", "IAND", "IOR", "INOT", "GOTO",
"IFFALSE GOTO", "INVOKEVIRTUAL", "IRETURN", "PRINT", "STOP"};
"ILOAD", "ICONST", "ISTORE", "IADD", "ISUB", "IMUL",
"IDIV", "ILT", "IGT", "IEQ", "IAND", "IOR",
"INOT", "GOTO", "IFFALSE GOTO", "INVOKEVIRTUAL", "IRETURN", "PRINT",
"STOP", "NEW", "NEWARRAY", "IALOAD", "IASTORE", "IALEN"};
#endif
23 changes: 14 additions & 9 deletions src/ir/CFG.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <algorithm>
#include <iostream>
#include <set>
#include <string>
#include <unordered_set>
#include <vector>
Expand Down Expand Up @@ -96,23 +97,27 @@ void CFG::generateBytecode(BytecodeProgram &program, SymbolTable &st) {

auto *methodScope = st.resolveScope(className, methodName);
const auto *method = dynamic_cast<Method *>(methodScope->getRecord());
const auto *classScope = methodScope->getParent();

const auto methodParameters = method->getParameterNames();
const auto &blockName = basicBlock->getName();
auto variableNames = methodScope->getVariableNames();
if (const auto *classScope = methodScope->getParent();
classScope != nullptr) {
const auto classVariableNames = classScope->getVariableNames();
variableNames.insert(classVariableNames.begin(),
classVariableNames.end());
}
const auto variableNames = methodScope->getVariableNames();
auto fieldVariableNames = classScope != nullptr
? classScope->getVariableNames()
: std::set<std::string>{};

std::vector<std::string> variables(variableNames.begin(),
variableNames.end());
auto &bytecodeMethod =
program.addBytecodeMethod(blockName, std::move(variables));
std::vector<std::string> fieldVariables(fieldVariableNames.begin(),
fieldVariableNames.end());
auto &bytecodeMethod = program.addBytecodeMethod(
blockName, std::move(variables), std::move(fieldVariables));
auto &bytecodeBlock = bytecodeMethod.addBytecodeMethodBlock(blockName);

if (basicBlock != mainRoot) {
bytecodeBlock.store("this");
}

std::for_each(methodParameters.rbegin(), methodParameters.rend(),
[&bytecodeBlock](const auto &param) {
bytecodeBlock.store(param);
Expand Down
20 changes: 18 additions & 2 deletions src/ir/Tac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,37 @@ void ArrayCopyTac::print(std::ostream &os) const {
os << result << "[" << lhs << "]"
<< " := " << rhs << "\n";
}
void ArrayCopyTac::generateBytecode(BytecodeMethodBlock &block) {
block.push(result).push(lhsOp).push(rhsOp).array_store();
}

void ArrayAccessTac::print(std::ostream &os) const {
os << result << " := " << lhs << "[" << rhs << "]\n";
}
void ArrayAccessTac::generateBytecode(BytecodeMethodBlock &block) {
block.push(lhsOp).push(rhsOp).array_load().store(result);
}

void ArrayLengthTac::print(std::ostream &os) const {
os << result << " := length " << rhs << "\n";
}
void ArrayLengthTac::generateBytecode(BytecodeMethodBlock &block) {
block.push(rhsOp).array_length().store(result);
}

void NewTac::print(std::ostream &os) const {
os << result << " := new " << rhs << "\n";
}
void NewTac::generateBytecode(BytecodeMethodBlock &block) {
block.new_object(rhs).store(result);
}

void NewArrayTac::print(std::ostream &os) const {
os << result << " := new int, " << rhs << "\n";
}
void NewArrayTac::generateBytecode(BytecodeMethodBlock &block) {
block.push(rhsOp).new_array().store(result);
}

void JumpTac::print(std::ostream &os) const { os << "goto " << result << "\n"; }
void JumpTac::generateBytecode(BytecodeMethodBlock &block) {
Expand All @@ -52,10 +67,11 @@ void CondJumpTac::generateBytecode(BytecodeMethodBlock &block) {
}

void MethodCallTac::print(std::ostream &os) const {
os << result << " := call " << lhs << ", " << rhs << "\n";
os << result << " := call " << op << " on " << lhs << ", " << rhs
<< " args\n";
}
void MethodCallTac::generateBytecode(BytecodeMethodBlock &block) {
block.call(lhs + "." + op).store(result);
block.push(lhsOp).call(op).store(result);
}

void ParamTac::print(std::ostream &os) const { os << "param " << rhs << "\n"; }
Expand Down
11 changes: 8 additions & 3 deletions src/ir/Tac.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,31 +50,36 @@ class ArrayCopyTac : public Tac {
const Operand &z_)
: Tac(result_, index_, ":=", z_) {};
void print(std::ostream &os) const override;
void generateBytecode(BytecodeMethodBlock &block) override;
};
class ArrayAccessTac : public Tac {
public:
ArrayAccessTac(const std::string &result_, const Operand &y_,
const Operand &z_)
: Tac(result_, y_, "", z_) {};
void print(std::ostream &os) const override;
void generateBytecode(BytecodeMethodBlock &block) override;
};
class ArrayLengthTac : public Tac {
public:
ArrayLengthTac(const std::string &result, const Operand &y_)
: Tac(result, y_) {};
void print(std::ostream &os) const override;
void generateBytecode(BytecodeMethodBlock &block) override;
};
class NewTac : public Tac {
public:
NewTac(const std::string &result, const Operand &y_) : Tac(result, y_) {};
void print(std::ostream &os) const override;
void generateBytecode(BytecodeMethodBlock &block) override;
};

class NewArrayTac : public Tac {
public:
NewArrayTac(const std::string &result, const Operand &length_)
: Tac(result, length_) {};
void print(std::ostream &os) const override;
void generateBytecode(BytecodeMethodBlock &block) override;
};

class NotTac : public Tac {
Expand Down Expand Up @@ -102,9 +107,9 @@ class CondJumpTac : public Tac {

class MethodCallTac : public Tac {
public:
MethodCallTac(const std::string &result, const std::string &objectName,
const Operand &methodName, const Operand &argCount)
: Tac(result, methodName, objectName, argCount) {};
MethodCallTac(const std::string &result, const Operand &receiver,
const std::string &methodTarget, const Operand &argCount)
: Tac(result, receiver, methodTarget, argCount) {};
void print(std::ostream &os) const override;
void generateBytecode(BytecodeMethodBlock &block) override;
};
Expand Down
Loading