Files
scully/src/test.cpp

166 lines
4.2 KiB
C++
Raw Normal View History

/* The scully programming language.
*
* Copyright (c) Peter Dahlberg, Markus Hauschild and Florian Sattler, 2013.
* Licensed under the GNU GPL v2.
*/
2013-05-31 23:51:44 +02:00
#include "Token.h"
2013-06-01 14:32:48 +02:00
#include "AST/CodeGenVisitor.h"
2013-06-01 14:29:18 +02:00
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/IRBuilder.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/DataLayout.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/TargetSelect.h"
2013-05-31 21:35:44 +02:00
// this file is auto generated from grammar/grammar.y
2013-05-31 22:20:31 +02:00
#include "grammar.h"
2013-05-31 21:35:44 +02:00
#include "lexertl/generator.hpp"
#include "lexertl/lookup.hpp"
#include "lexertl/rules.hpp"
#include "lexertl/state_machine.hpp"
int main() {
2013-06-01 22:36:15 +02:00
srand(42);
2013-06-01 23:51:43 +02:00
bool debugParser = true;
bool debugCodeGen = true;
2013-05-31 22:20:31 +02:00
lexertl::rules rules;
lexertl::state_machine state_machine;
//keywords
rules.add("bool", T_BOOL);
rules.add("for", T_FOR);
rules.add("if", T_IF);
rules.add("int", T_INT);
rules.add("return", T_RETURN);
rules.add("void", T_VOID);
rules.add("rfor", T_RFOR);
rules.add("rif", T_RIF);
2013-06-01 17:22:52 +02:00
rules.add("string", T_STRING);
2013-05-31 22:20:31 +02:00
// special characters
2013-06-01 22:36:15 +02:00
//rules.add("\"(\"", T_LPAREN);
//rules.add("\")\"", T_RPAREN);
rules.add("dana", T_LPAREN);
rules.add("fox", T_RPAREN);
2013-05-31 22:20:31 +02:00
rules.add("mulder", T_BEGIN);
rules.add("scully", T_END);
rules.add(",", T_COMMA);
rules.add(";", T_SEMICOLON);
// operators
rules.add("=", T_ASSIGN);
rules.add("==", T_EQUALS);
rules.add("<", T_LESS);
rules.add("\"+\"", T_PLUS);
rules.add("\"-\"", T_MINUS);
rules.add("\"*\"", T_TIMES);
rules.add("\"/\"", T_DIV);
// constants
rules.add("true", T_TRUE);
rules.add("false", T_FALSE);
rules.add("\\d+", T_CINT);
// identifier
rules.add("[a-zA-Z_][a-zA-Z_0-9]*", T_IDENTIFIER);
// whitespace
rules.add("\\s+", T_WHITESPACE);
lexertl::generator::build(rules, state_machine);
state_machine.minimise();
2013-06-01 14:29:18 +02:00
std::cout << "The scully programming language v0.2" << std::endl;
// Setup LLVM JIT
llvm::InitializeNativeTarget();
llvm::Module* module = new llvm::Module("SCULLY/JIT", llvm::getGlobalContext());
std::string errStr;
llvm::ExecutionEngine* ee = llvm::EngineBuilder(module).setErrorStr(&errStr).create();
if (!ee) {
std::cerr << "Error creating Execution Engine: " << errStr << std::endl;
return 1;
}
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
llvm::FunctionPassManager* fpm = new llvm::FunctionPassManager(module);
fpm->add(new llvm::DataLayout(*ee->getDataLayout()));
// Provide basic AliasAnalysis support for GVN.
fpm->add(llvm::createBasicAliasAnalysisPass());
// Do simple "peephole" optimizations and bit-twiddling optzns.
fpm->add(llvm::createInstructionCombiningPass());
// Reassociate expressions.
fpm->add(llvm::createReassociatePass());
// Eliminate Common SubExpressions.
fpm->add(llvm::createGVNPass());
// Simplify the control flow graph (deleting unreachable blocks, etc).
fpm->add(llvm::createCFGSimplificationPass());
fpm->doInitialization();
2013-06-01 21:10:05 +02:00
CodeGenVisitor* cv = new CodeGenVisitor(module, fpm, ee);
2013-05-31 22:20:31 +02:00
2013-05-31 23:51:44 +02:00
void* parser = scullyParserAlloc(malloc);
2013-05-31 22:20:31 +02:00
while (true) {
std::cout << "> ";
std::string input;
std::getline(std::cin, input);
if (std::cin.eof()) {
std::cout << std::endl << "Bye." << std::endl;
return 0;
}
if (input == "@dp") {
debugParser = !debugParser;
std::cout << "Debugging for the parser: " << debugParser << std::endl;
continue;
}
if (input == "@dc") {
debugCodeGen = !debugCodeGen;
std::cout << "Debugging for the code generation: " << debugCodeGen << std::endl;
continue;
}
2013-05-31 22:20:31 +02:00
auto iter = input.begin();
auto end = input.end();
lexertl::smatch results(iter, end);
do {
lexertl::lookup (state_machine, results);
std::string s(results.start, results.end);
if (results.id != T_WHITESPACE) {
//std::cout << "Id: " << results.id << ", Token: " << s << std::endl;
2013-06-01 22:36:15 +02:00
try {
scullyParser(parser, results.id, new Token(s), cv);
} catch (const char* c) {
std::cerr << "Error: " << c << std::endl;
}
2013-05-31 22:20:31 +02:00
}
} while (results.id != 0);
2013-06-01 14:29:18 +02:00
if (debugCodeGen) {
module->dump();
}
2013-05-31 22:20:31 +02:00
}
2013-05-31 23:51:44 +02:00
scullyParserFree(parser, free);
2013-05-31 22:20:31 +02:00
return 0;
}