Commit 22f00483 authored by zygzagZ's avatar zygzagZ

Strings work

parent 69a63946
......@@ -3,6 +3,7 @@
// ld -m elf_i386 -L. -e main runtime.o hello32.o -lc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int printInt(int a) {
printf("%d\n", a);
......@@ -63,3 +64,13 @@ char* __latte_mem_init_array(int len, size_t size, void* virtTab) {
}
return buf;
}
char* __latte_concat(const char *l, const char *r) {
char *buf = malloc(strlen(l)+strlen(r)+1);
if (!buf) error();
char *t = buf;
while (*l) *(t++) = *(l++);
while (*r) *(t++) = *(r++);
*t = 0;
return buf;
}
\ No newline at end of file
......@@ -44,19 +44,24 @@ string Compiler::compile(Visitable *v) {
compileFunction(f);
}
for (const auto& it : quadGen.getStrings()) {
buf << "_str_" << it.second << ":\n"
<< ".string " << std::quoted(it.first) << "\n";
}
return buf.str();
}
void Compiler::compileFunction(const FunctionInfoPtr& f) {
string name = mangleFunctionName(f);
buf << ".globl \"" << name << "\"\n";
buf << ".globl " << quoted(name) << "\n";
if (!f->block) return;
// TODO: jeśli funkcja jest klasowa, ustawić self na ... wartosc z ecx
// c++ thiscall ecx, stack right-to-left (push c, push b, push a)
buf << "\"" << name << "\":\n";
buf << quoted(name) << ":\n";
stringstream asmGen;
swap(buf, asmGen);
exitLabel = make_shared<QLabel>("." + name + "_exit");
......@@ -81,7 +86,7 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
buf << "\tsub $" + to_string(localsCount * 4) << ",%esp\n";
}
buf << asmGen.str();
buf << "\"" << exitLabel->label << "\":\n" <<
buf << quoted(exitLabel->label) << ":\n" <<
"\tMOVL %ebp, %esp\n"
"\tPOP %ebp\n";
for (auto i = Register::calleeSaved.rbegin(); i != Register::calleeSaved.rend(); i++)
......@@ -94,7 +99,7 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
localInfos.clear();
}
void Compiler::printFunction(QuadrupleGenerator::Result quadEnv, const FunctionInfoPtr& f) {
void Compiler::printFunction(const QuadrupleGenerator::Result& quadEnv, const FunctionInfoPtr& f) {
int blkNo = 0;
buf << COMMENT "\x1b[32;1mFunction " << mangleFunctionName(f) << "\x1b[0m" << endl;
for (const auto& b : quadEnv.blocks) {
......@@ -175,6 +180,10 @@ const vector<Register> Register::assignable = {1,4,5,2,3}; // ecx and edx least
string Compiler::getRef(const VariablePtr &v) {
if (v->constExpr) {
Str s;
if (v->type->isEqual(&s) && v->val != 0) {
return "$_str_" + to_string(v->val);
}
return "$" + to_string(v->val);
}
if (v->registerColor == 0) {
......@@ -215,14 +224,14 @@ void Compiler::generateQReturn(QReturn &q) {
if (q.val)
moveTo(q.val, 0);
append("JMP", "\"" + exitLabel->label + "\"");
append("JMP", quote(exitLabel->label));
}
void Compiler::generateQCall(QCall &q) {
if (q.self) {
throw runtime_error("Class call unimplemented!");
}
append("CALL", "\"" + mangleFunctionName(q.fn) + "\"");
append("CALL", quote(mangleFunctionName(q.fn)));
if (q.params) {
append("ADDL", "$" + to_string(q.params*4), "%esp");
}
......@@ -461,7 +470,7 @@ void Compiler::generateQAssign(QAssign &q) {
}
void Compiler::generateQLabel(QLabel &q) {
buf << "\"" << q.label << "\":" << endl;
buf << quoted(q.label) << ":" << endl;
}
void Compiler::generateQPhi(QPhi &q) {
......
......@@ -85,7 +85,7 @@ private:
unordered_set<VarInfoPtr> localInfos;
void compileFunction(const FunctionInfoPtr& f);
void printFunction(QuadrupleGenerator::Result quadEnv, const FunctionInfoPtr& f);
void printFunction(const QuadrupleGenerator::Result& quadEnv, const FunctionInfoPtr& f);
string getRef(const VariablePtr &v);
void generatePhiXCHG(const map<VariablePtr, VariablePtr> &varMap);
......@@ -164,12 +164,12 @@ private:
string getBlockLabelText(BasicBlockPtr &b) {
auto n = b->getName();
if (n.empty()) throw runtime_error("Attempt to get label text of unlabeled block");
return "\"" + n + "\"";
return quote(n);
}
shared_ptr<QLabel> exitLabel;
void generateStandardReturn() {
append("JMP", "\"" + exitLabel->label + "\"");
append("JMP", quote(exitLabel->label));
}
static vector<Register> aliveAfter(Quadruple &q, const vector<Register> &vec) {
......
......@@ -2,6 +2,8 @@
#include "Info.h"
#include "Printer.h"
#include <sstream>
#include <iomanip>
using namespace std;
ParseError::ParseError(string reason, int line) : runtime_error("ParseError"), line(line)
......@@ -24,14 +26,14 @@ ParseError::ParseError(string reason, VarInfo &var) : runtime_error("ParseError"
RedefinedError::RedefinedError(PIdent *ident, VarInfoPtr orig) {
stringstream ss;
ss << "Variable \"" << ident->string_ << "\" at line " << ident->lineno << " redeclared! First declaration at line " << orig->lineLocation;
ss << "Variable " << quoted(ident->string_) << " at line " << ident->lineno << " redeclared! First declaration at line " << orig->lineLocation;
msg = ss.str();
line = ident->lineno;
}
UndefinedError::UndefinedError(PIdent *ident) {
stringstream ss;
ss << "Undefined reference to \"" << ident->string_ << "\" at line " << ident->lineno;
ss << "Undefined reference to " << quoted(ident->string_) << " at line " << ident->lineno;
msg = ss.str();
line = ident->lineno;
}
......
......@@ -548,9 +548,10 @@ void TypeCheck::addIOFunctions(Type &type) {
}
void TypeCheck::setupEnv() {
{ Int x; addIOFunctions(x); }
{ Str x; addIOFunctions(x); }
// { Bool x; addIOFunctions(x); }
Int _int;
Str _str;
addIOFunctions(_int);
addIOFunctions(_str);
// void error()
{
......@@ -560,6 +561,16 @@ void TypeCheck::setupEnv() {
scope->functions << error;
}
// concat
{
auto *v = new ListType();
v->push_back(_str.clone());
v->push_back(_str.clone());
TypePtr fun = make_shared<Fun>(_str.clone(), v);
FunctionInfoPtr concat = make_shared<FunctionInfo>("__latte_concat", fun);
scope->functions << concat;
}
arrayLengthVar = make_shared<VarInfo>("length", make_shared<Int>());
}
......
......@@ -7,7 +7,7 @@
#include <cassert>
#include "Variable.h"
#include "Quadruple.h"
#include "setOverloads.h"
#include "Util.h"
using namespace std;
......
......@@ -5,7 +5,8 @@
#include "../Info.h"
#include "Variable.h"
#include "setOverloads.h"
#include "Util.h"
using namespace std;
class Compiler;
......@@ -101,7 +102,7 @@ public:
class QLabel : public Quadruple {
public:
string label;
std::string toString() const override { return Quadruple::toString() + "\"" + label + "\":"; }
std::string toString() const override { return Quadruple::toString() + quote(label) + ":"; }
explicit QLabel(std::string comment) : label(std::move(comment)) {}
void generateAsm(Compiler &c) override;
};
......@@ -134,7 +135,7 @@ public:
explicit QJump(shared_ptr<QLabel> target) : target(std::move(target)) {};
std::string toString() const override {
return Quadruple::toString() + "jump \"" + target->label + "\"";
return Quadruple::toString() + "jump " + quote(target->label);
}
bool isFinal() const override { return true; }
......
......@@ -6,7 +6,7 @@
#include "QuadrupleGenerator.h"
QuadrupleGenerator::Result QuadrupleGenerator::compileFunction(FunctionInfoPtr f) {
if (!f->block) return {};
if (!f->block) return QuadrupleGenerator::Result(strings);
scope->currentFunction = f;
newBlock();
......@@ -57,14 +57,8 @@ QuadrupleGenerator::Result QuadrupleGenerator::compileFunction(FunctionInfoPtr f
for (const auto& v : vars) {
if (v->info)
v->info->loc = nullptr;
// TODO: wypisywanie zmiennych
/*cout << "\nvar " << v->name << endl;
for (const auto& q : v->writes)
cout << q->toString() << endl;
for (const auto& q : v->uses)
cout << q->toString() << endl;*/
}
QuadrupleGenerator::Result ret;
}
QuadrupleGenerator::Result ret(strings);
vars.swap(ret.vars);
blocks.swap(ret.blocks);
......@@ -126,12 +120,13 @@ void QuadrupleGenerator::visitELitFalse(ELitFalse *p) {
}
void QuadrupleGenerator::visitEString(EString *p) {
// TODO: zrobic liste stringow per app
lastVar = alloc();
lastVar = alloc(getStringId(p->string_));
lastVar->type = p->type;
}
void QuadrupleGenerator::visitNullCast(NullCast *p) {
lastVar = alloc(0);
lastVar->type = p->type;
}
void QuadrupleGenerator::visitNeg(Neg *p) {
......@@ -175,6 +170,15 @@ void QuadrupleGenerator::visitEAdd(EAdd *p) {
auto r = evalExpr(p->expr_2);
lastVar = alloc();
p->addop_->accept(this);
Str s;
if (p->type->isEqual(&s)) {
auto call = make_shared<QCall>(lastVar, scope->functions.local("__latte_concat"), 2, nullptr);
addQuad<QParam>(r, 1, call);
addQuad<QParam>(l, 2, call);
addQuad(call);
return;
}
addQuad<QAssign>(lastVar, l, op, r);
if ((lastVar->constExpr = l->constExpr && r->constExpr)) {
if (op == Op::Minus)
......
......@@ -12,19 +12,24 @@
#include "../Info.h"
#include "Quadruple.h"
#include "BasicBlock.h"
#include <unordered_map>
class QuadrupleGenerator : public Skeleton {
public:
struct Result {
explicit Result(const unordered_map<string, int> &s) : strings(s) {};
vector<BasicBlockPtr> blocks;
vector<VariablePtr> vars;
const unordered_map<string, int> &strings;
};
explicit QuadrupleGenerator(shared_ptr<Scope> s) : lineno(0), scope(std::move(s)) {}
Result compileFunction(FunctionInfoPtr f);
const unordered_map<string, int> &getStrings() const { return strings; };
private:
vector<VariablePtr> vars;
vector<BasicBlockPtr> blocks;
unordered_map<string, int> strings;
Quadruple::Op op;
BasicBlockPtr block;
VariablePtr lastVar;
......@@ -125,6 +130,11 @@ private:
}
}
int getStringId(const string& s) {
auto it = strings.emplace(s, strings.size() + 1);
return it.first->second;
}
BasicBlockPtr flushBasicBlock(bool append = false);
void visitPlus(Plus *p) override { op = Quadruple::Op::Plus; }
......
#include "RegisterAllocator.h"
#include "BasicBlock.h"
#include "setOverloads.h"
#include "Util.h"
#include <fstream>
#include "../Compiler.h"
......
#ifndef ZAD2_SETOVERLOADS_H
#define ZAD2_SETOVERLOADS_H
#ifndef ZAD2_UTIL_H
#define ZAD2_UTIL_H
#include <set>
using namespace std;
......@@ -61,4 +61,12 @@ set<typename C::value_type> to_set(const C &v) {
return res;
}
#endif //ZAD2_SETOVERLOADS_H
#include <iomanip>
template<typename T>
string quote(const T& str) {
stringstream s;
s << quoted(str);
return s.str();
}
#endif //ZAD2_UTIL_H
......@@ -8,6 +8,11 @@ int a() {
}
int main() {
{
string a = "Hello", b = " ", c = "world!";
printString(a + b + c);
printString("Quote test \" works \" yay");
}
{
int e, a = 1, b = 2, c = 3, d = 4, f = 5, g = 6;
while (e < 10) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment