Commit 22f00483 authored by zygzagZ's avatar zygzagZ

Strings work

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