Skip to content

Commit

Permalink
Merge pull request #39 from elite-lang/dev
Browse files Browse the repository at this point in the history
v0.9.1
  • Loading branch information
xssss1 committed Mar 7, 2016
2 parents 91b0a7f + 20fd346 commit e7d636a
Show file tree
Hide file tree
Showing 26 changed files with 1,223 additions and 99 deletions.
35 changes: 28 additions & 7 deletions Builder/include/Builder.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* @Author: sxf
* @Date: 2015-11-08 09:06:35
* @Last Modified by: sxf
Expand All @@ -10,6 +10,7 @@
#define BUILDER_H

#include <string>
#include "PathSet.h"

class Worker;

Expand All @@ -21,15 +22,18 @@ class Builder
public:
// 构建一个文件
int BuildFile(std::string filename);

// 构建其中指定的路径
int BuildPath(std::string filepath, bool isRecursive = false);
int BuildPath(std::string package, bool isRecursive = false);

// 自动构建源代码目录下的全部内容
int BuildAll();

// 添加一个链接文件, 如果是bc的话, 会自动用llc编译成本地文件, 如果是.o则直接链接
int AddLinkFile(std::string filename);

// 添加一个链接路径
int AddLinkPath(std::string filepath);
int AddLinkPath(std::string path);

// 设置构建路径
int SetBuildPath(std::string path);
Expand All @@ -38,7 +42,7 @@ class Builder
int PreBuildAll();

// 添加源代码的搜索路径
int AddSearchPath(std::string path);
int AddSrcPath(std::string path);

// 添加库路径
int AddLibPath(std::string path);
Expand All @@ -56,6 +60,9 @@ class Builder
static Builder* Create(Worker* worker = 0);
void Close();


static int call_llc(std::string filein);
static int call_ld(std::string filein, std::string fileout, std::string link_args);
protected:
Builder(Worker* worker = 0);
~Builder();
Expand All @@ -67,8 +74,22 @@ class Builder
static std::string make_default_name(const char* filename);
static std::string get_file_name(const char* filename);

int call_llc(std::string filein);
int call_ld(std::string filein, std::string fileout);


/**
* 程序源文件目录
*/
PathSet src_paths;

/**
* 程序库目录
*/
PathSet lib_paths;

/**
* 需要链接的C库目录
*/
PathSet link_paths;

};

Expand Down
62 changes: 62 additions & 0 deletions Builder/include/PathSet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* @Author: sxf
* @Date: 2015-11-08 09:17:30
* @Last Modified by: sxf
* @Last Modified time: 2015-12-22 08:23:22
*/

#ifndef PATH_SET_H
#define PATH_SET_H

#include <vector>
#include <string>

class PathSet_private;

/**
* @brief 搜索路径集合
*/
class PathSet
{
public:
PathSet();
~PathSet();

/**
* 添加一个路径
* @method AddPath
* @param path 要添加的目录(绝对路径)
*/
void AddPath(const std::string& path);

/**
* 查找一个文件在该路径集合中的位置
* @method FindFile
* @param filename 文件名
* @return 第一个找到的文件的绝对路径
*/
std::string FindFile(const std::string& filename);

/**
* 查找一个包的全部位置
* @method FindPackage
* @param package 包名
* @return 返回全部找到的包的绝对路径
*/
std::vector<std::string> FindPackage(const std::string& package);

/**
* 查找目录中全部的包
* @method FindAllPackageName
* @return 返回全部找到的包的名字
*/
std::vector<std::string> FindAllPackageName();

const std::vector<std::string>& getPaths() { return paths; }
protected:
std::vector<std::string> paths;
PathSet_private* priv;
};


#endif // PATH_SET_H
9 changes: 5 additions & 4 deletions Builder/include/Worker.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* @Author: sxf
* @Date: 2015-11-11 13:52:11
* @Last Modified by: sxf
Expand All @@ -12,7 +12,7 @@ class Parser;
class ScriptRunner;
class CodeGen;
class Builder;

class Node;
/**
* @brief 工作流类, 是词法分析器, 语法分析器, 元脚本解析器, 后端代码生成器整合后的工作流
*/
Expand All @@ -22,7 +22,8 @@ class Worker
void Init(LexInterface* l, Parser* p, ScriptRunner* s, CodeGen* c);
void Run(const char* input, const char* output);
void MetaGen(const char* output);

Node* MakeAST(const char* input);

static Worker* CreateDefault(const char* lex_cfg, const char* parser_cfg, const char* package_path, Builder* b);
static Worker* Create(LexInterface* l, Parser* p, ScriptRunner* s, CodeGen* c, Builder* b);

Expand All @@ -31,7 +32,7 @@ class Worker
ScriptRunner* getScriptRunner() { return script_runner; }
CodeGen* getCodegen() { return codegen; }
Builder* getBuilder() { return builder; }

Worker();
~Worker();
protected:
Expand Down
116 changes: 104 additions & 12 deletions Builder/src/Builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,69 @@
#include "FileUtils.h"
#include <cstring>
#include <iostream>
#include <map>
#include <fstream>
#include <cstdlib>
#include <streambuf>
#include "PathUtils.h"
#include "DebugMsg.h"

#include "PackageChanger.hpp"
#include "CodeGen.h"
using namespace std;


class builder_scanner : public IFileTraversal {
public:
virtual void Work(const std::string& now_path,
const std::string& filename,
const std::string& suffix)
{
printf("%s %s %s\n", now_path.c_str(), filename.c_str(), suffix.c_str());
if (suffix == ".elite") {
string filepath = now_path + "/" + filename;
filepath = PathUtils::native(filepath);

string outfile_path = this->buildpath + "/" +
path_name + "/" + filename;
int n = outfile_path.find(".elite");
outfile_path.replace(n, 6, ".bc");
outfile_path = PathUtils::native(outfile_path); // 本地化

string data = FileUtils::fileReader(filepath.c_str());
printf("输入文件: %s \n输出文件: %s\n", filepath.c_str(), outfile_path.c_str());
Node* node = worker->MakeAST(data.c_str());
file_map[outfile_path] = node;
FileUtils::create_directories(PathUtils::parent_path(outfile_path));
}
}

void MakeAll() {
set<Node*> pset;
for (auto item : file_map) pset.insert(item.second);
worker->getCodegen()->PreScan(pset);

for (auto item : file_map) {
worker->getCodegen()->Make(item.second, item.first.c_str(), package_name.c_str());
Builder::call_llc(item.first);
string objname = item.first;
int n = objname.find(".bc");
objname.replace(n, 3, ".o");
objname = PathUtils::native(objname); // 本地化
objname_list += " ";
objname_list += objname;
}
}

Worker* worker;
string buildpath;
string package_name;
string path_name;
string objname_list;
map< string, Node* > file_map;
};



// 构建一个文件
int Builder::BuildFile(std::string filename) {
if (!PathGetter::testFile(filename.c_str())) {
Expand Down Expand Up @@ -51,27 +106,63 @@ int Builder::BuildFile(std::string filename) {
program_path = PathUtils::native(program_path); // 本地化

printf("输入文件: %s \n输出文件: %s\n", objname.c_str(), program_path.c_str());
int ret = call_ld( objname + " " + objmeta, program_path);
int ret = call_ld( objname + " " + objmeta, program_path, link_args);

return 0;
return ret;
}


// 构建其中指定的路径(构建其中一个包)
int Builder::BuildPath(std::string package, bool isRecursive) {
builder_scanner bs;
bs.worker = worker;
bs.buildpath = buildpath;
bs.package_name = package;
bs.path_name = PackageChanger::pname2path(package);
printf("package_name: %s\n", package.c_str());
printf("path_name: %s\n", bs.path_name.c_str());

auto vec = src_paths.FindPackage(package);
for (string& item : vec) {
printf("package_path: %s\n", item.c_str());
FileUtils::dir_traversal(item, bs, FileUtils::only_file);
}
bs.MakeAll();

// 生成meta
string meta_path = buildpath + "/" + bs.path_name + "/meta.bc";
meta_path = PathUtils::native(meta_path); // 本地化
worker->MetaGen(meta_path.c_str());
call_llc(meta_path);

string meta_obj = meta_path;
int n = meta_obj.find(".bc");
meta_obj.replace(n, 3, ".o");
meta_obj = PathUtils::native(meta_obj); // 本地化

string program_path = this->buildpath + "/run";
program_path = PathUtils::native(program_path); // 本地化
int ret = call_ld( bs.objname_list + " " + meta_obj, program_path, link_args);
return ret;
}


// 构建其中指定的路径
int Builder::BuildPath(std::string filepath, bool isRecursive) {
int Builder::BuildAll() {


return 0;
}


// 添加一个链接文件, 如果是bc的话, 会自动用llc编译成本地文件, 如果是.o则直接链接
int AddLinkFile(std::string filename) {
int Builder::AddLinkFile(std::string filename) {
return 0;
}


// 添加一个链接路径
int AddLinkPath(std::string filepath) {
int Builder::AddLinkPath(std::string path) {
link_paths.AddPath(PathUtils::native(path));
return 0;
}

Expand All @@ -82,13 +173,15 @@ int Builder::PreBuildAll() {


// 添加源代码的搜索路径
int Builder::AddSearchPath(std::string path) {
int Builder::AddSrcPath(std::string path) {
src_paths.AddPath(PathUtils::native(path));
return 0;
}


// 添加库路径
int Builder::AddLibPath(std::string path) {
lib_paths.AddPath(PathUtils::native(path));
return 0;
}

Expand Down Expand Up @@ -155,9 +248,8 @@ string Builder::get_file_name(const char* filename) {
const char* file;
if (ans == 0) file = filename;
else file = ans+1;
int size = 0;
for (const char* p = file; *p != 0; ++p, ++size)
if (*p == '.') break;
int size = strrchr(file, '.') - file;
if (size <= 0) { string s = file; return s; }
char* str = new char[size+1];
strncpy(str, file, size);
str[size] = 0;
Expand Down Expand Up @@ -185,7 +277,7 @@ int Builder::call_llc(std::string filein) {
return 0;
}

int Builder::call_ld(std::string filein, std::string fileout) {
int Builder::call_ld(std::string filein, std::string fileout, std::string link_args) {

#if !defined(_WIN32) && (defined(__linux__) || defined(__APPLE__))
string ld = "clang++";
Expand Down
29 changes: 29 additions & 0 deletions Builder/src/PackageChanger.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef PACKAGE_CHANGER_H
#define PACKAGE_CHANGER_H

#include <string>

class PackageChanger {
public:
static std::string pname2path(const std::string& name) {
std::string str = name;
for (auto& i : str) {
if (i == '.') i = '/';
}
return str;
}

static std::string path2pname(const std::string& path) {
std::string str = path;
if (*(str.begin()) == '/') str.erase(str.begin());
if (*(str.rbegin()) == '/') str.erase(--str.end());
for (auto& i : str) {
if (i == '/') i = '.';
}
return str;
}
};



#endif /* end of include guard: PACKAGE_CHANGER_H */
Loading

0 comments on commit e7d636a

Please sign in to comment.