basic tests
This commit is contained in:
parent
2a04b62f45
commit
4ae6c97904
25 changed files with 158 additions and 25 deletions
10
makefile
10
makefile
|
|
@ -5,7 +5,7 @@ FLEX = flex
|
|||
|
||||
TARGET = build/py2rb
|
||||
|
||||
$(TARGET): build/parser.o build/lexer.o build/main.o
|
||||
$(TARGET): build/parser.o build/lexer.o build/main.o
|
||||
$(CXX) $^ -o $@
|
||||
|
||||
build/parser.cpp build/parser.hpp: src/parser.y | build
|
||||
|
|
@ -17,11 +17,13 @@ build/lexer.cpp build/lexer.hpp: src/lexer.l build/parser.hpp src/scanner.hpp sr
|
|||
build/%.o: build/%.cpp
|
||||
$(CXX) -c $(ARGS) $< -o $@
|
||||
|
||||
build/%.o: src/%.cpp | build
|
||||
$(CXX) -c $(ARGS) $< -o $@
|
||||
build/main.o: src/main.cpp build src/codegen.hpp
|
||||
$(CXX) -c $(ARGS) src/main.cpp -o build/main.o
|
||||
|
||||
src/ast.hpp: src/ast/base.hpp src/ast/expressions.hpp src/ast/literals.hpp src/ast/operators.hpp src/ast/statements.hpp src/ast/string_utils.hpp
|
||||
|
||||
src/codegen.hpp : src/ast.hpp
|
||||
|
||||
build:
|
||||
mkdir -p build
|
||||
|
||||
|
|
@ -34,4 +36,4 @@ run: $(TARGET)
|
|||
test: $(TARGET)
|
||||
test/tester.sh
|
||||
|
||||
.PHONY: clean run test
|
||||
.PHONY: clean run test
|
||||
|
|
|
|||
125
src/codegen.hpp
Normal file
125
src/codegen.hpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#pragma once
|
||||
#include "ast.hpp"
|
||||
#include <sstream>
|
||||
|
||||
class RubyGenerator
|
||||
{
|
||||
std::ostringstream output;
|
||||
int indent_level = 0;
|
||||
|
||||
void write_indent()
|
||||
{
|
||||
for (int i = 0; i < indent_level; i++)
|
||||
{
|
||||
output << " ";
|
||||
}
|
||||
}
|
||||
|
||||
void write(const std::string &s)
|
||||
{
|
||||
output << s;
|
||||
}
|
||||
|
||||
public:
|
||||
std::string generate(const Module &module)
|
||||
{
|
||||
output.str("");
|
||||
indent_level = 0;
|
||||
|
||||
for (const auto &stmt : module.body)
|
||||
{
|
||||
generate_stmt(*stmt);
|
||||
}
|
||||
|
||||
return output.str();
|
||||
}
|
||||
|
||||
private:
|
||||
void generate_stmt(const Stmt &stmt)
|
||||
{
|
||||
if (auto *expr_stmt = dynamic_cast<const ExprStmt *>(&stmt))
|
||||
{
|
||||
write_indent();
|
||||
generate_expr(*expr_stmt->expr);
|
||||
write("\n");
|
||||
}
|
||||
else if (auto *assign = dynamic_cast<const Assign *>(&stmt))
|
||||
{
|
||||
write_indent();
|
||||
generate_expr(*assign->target);
|
||||
write(" = ");
|
||||
generate_expr(*assign->value);
|
||||
write("\n");
|
||||
}
|
||||
else if (auto *if_stmt = dynamic_cast<const If *>(&stmt))
|
||||
{
|
||||
write_indent();
|
||||
write("if ");
|
||||
generate_expr(*if_stmt->condition);
|
||||
write("\n");
|
||||
|
||||
indent_level++;
|
||||
for (const auto &s : if_stmt->then_body)
|
||||
{
|
||||
generate_stmt(*s);
|
||||
}
|
||||
indent_level--;
|
||||
|
||||
if (!if_stmt->else_body.empty())
|
||||
{
|
||||
write("else\n");
|
||||
indent_level++;
|
||||
for (const auto &s : if_stmt->else_body)
|
||||
{
|
||||
generate_stmt(*s);
|
||||
}
|
||||
indent_level--;
|
||||
}
|
||||
|
||||
write("end\n");
|
||||
}
|
||||
else if (auto *ret = dynamic_cast<const Return *>(&stmt))
|
||||
{
|
||||
write_indent();
|
||||
write("return ");
|
||||
if (ret->value)
|
||||
{
|
||||
generate_expr(*ret->value);
|
||||
}
|
||||
write("\n");
|
||||
}
|
||||
}
|
||||
void generate_expr(const Expr &expr)
|
||||
{
|
||||
if (auto *num = dynamic_cast<const Number *>(&expr))
|
||||
{
|
||||
write(num->value);
|
||||
}
|
||||
else if (auto *id = dynamic_cast<const Identifier *>(&expr))
|
||||
{
|
||||
write(id->name);
|
||||
}
|
||||
else if (auto *str = dynamic_cast<const String *>(&expr))
|
||||
{
|
||||
write("\"" + str->value + "\"");
|
||||
}
|
||||
else if (auto *binop = dynamic_cast<const BinOp *>(&expr))
|
||||
{
|
||||
generate_expr(*binop->left);
|
||||
write(" " + binop->op.symbol() + " ");
|
||||
generate_expr(*binop->right);
|
||||
}
|
||||
else if (auto *call = dynamic_cast<const Call *>(&expr))
|
||||
{
|
||||
generate_expr(*call->func);
|
||||
write("(");
|
||||
for (size_t i = 0; i < call->args.size(); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
write(", ");
|
||||
generate_expr(*call->args[i]);
|
||||
}
|
||||
write(")");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
#include "parser.hpp"
|
||||
#include "scanner.hpp"
|
||||
#include "ast.hpp"
|
||||
#include "codegen.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
|
|
@ -71,5 +72,9 @@ int main(int argc, char *argv[])
|
|||
if (ast_dump)
|
||||
{
|
||||
std::cout << ast_root->dump();
|
||||
return 0;
|
||||
}
|
||||
|
||||
RubyGenerator generator;
|
||||
std::cout << generator.generate(*ast_root);
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
42
|
||||
42
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
x
|
||||
x
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
x = 5
|
||||
x = 5
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
2 + 3
|
||||
2 + 3
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
x = 2 + 3
|
||||
x = 2 + 3
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
x = 5
|
||||
y = 10
|
||||
y = 10
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
foo()
|
||||
foo()
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
print(x, y)
|
||||
print(x, y)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
if x
|
||||
y = 5
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@ if x
|
|||
y = 5
|
||||
else
|
||||
y = 10
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
for i in items
|
||||
print(i)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
while x
|
||||
x = x - 1
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
def add(a, b)
|
||||
return a + b
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@ if x
|
|||
if y
|
||||
z = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
[1, 2, 3]
|
||||
[1, 2, 3]
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
obj.method()
|
||||
|
|
@ -1 +1 @@
|
|||
lst[0]
|
||||
lst[0]
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
"hello"
|
||||
"hello"
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
x and y
|
||||
x and y
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
not x
|
||||
not x
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ class Point
|
|||
@x = x
|
||||
@y = y
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@ class Counter
|
|||
def increment
|
||||
@count = @count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue