Compare commits
No commits in common. '7dd4ceb63f30e754cc932551f5b7062d5df0d600' and '05ee67846ce2cb14ede1d43edd1b89ee33f54e38' have entirely different histories.
7dd4ceb63f
...
05ee67846c
@ -1,3 +0,0 @@
|
|||||||
.vscode
|
|
||||||
build
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
project(SysYFCompiler)
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.5)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -Wall -Wextra -Wno-unused -Wshadow -g -pedantic")
|
|
||||||
|
|
||||||
# include generated files in project environment
|
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/AST)
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/ErrorReporter)
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/Frontend)
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/SysYFIR)
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/SysYFIRBuilder)
|
|
||||||
|
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/AST)
|
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/ErrorReporter)
|
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/Frontend)
|
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/SysYFIR)
|
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/SysYFIRBuilder)
|
|
||||||
|
|
||||||
add_executable(
|
|
||||||
SysYFCompiler
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(
|
|
||||||
SysYFCompiler
|
|
||||||
SysYFIRBuilder
|
|
||||||
IRLib
|
|
||||||
Driver
|
|
||||||
ASTPrinter
|
|
||||||
ErrReporter
|
|
||||||
)
|
|
@ -1,28 +0,0 @@
|
|||||||
int num[2] = {4, 8};
|
|
||||||
int x[1];
|
|
||||||
int n;
|
|
||||||
int tmp = 1;
|
|
||||||
|
|
||||||
int climbStairs(int n) {
|
|
||||||
if(n < 4)
|
|
||||||
return n;
|
|
||||||
int dp[10];
|
|
||||||
dp[0] = 0;
|
|
||||||
dp[1] = 1;
|
|
||||||
dp[2] = 2;
|
|
||||||
int i;
|
|
||||||
i = 3;
|
|
||||||
while(i<n+1){
|
|
||||||
dp[i] = dp[i-1] + dp[i-2];
|
|
||||||
i = i + 1;
|
|
||||||
}
|
|
||||||
return dp[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
int res;
|
|
||||||
n=num[0];
|
|
||||||
x[0] = num[tmp];
|
|
||||||
res = climbStairs(n + tmp);
|
|
||||||
return res - x[0];
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
define i32 @main() #0 {
|
|
||||||
; alloc b and store 1.8 to b
|
|
||||||
%1 = alloca float, align 4 ;b
|
|
||||||
store float 0x3FFCCCCCC0000000, float* %1, align 4
|
|
||||||
|
|
||||||
; alloc a[2] and store 2 to a[0]
|
|
||||||
%2 = alloca [2 x i32], align 4 ;a
|
|
||||||
%3 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0 ;a[0]
|
|
||||||
store i32 2, i32* %3
|
|
||||||
|
|
||||||
; load b
|
|
||||||
%4 = load float, float* %1, align 4
|
|
||||||
|
|
||||||
; load a[0] and convert to float
|
|
||||||
%5 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0 ;a[0]
|
|
||||||
%6 = load i32, i32* %5, align 4
|
|
||||||
%7 = sitofp i32 %6 to float ;a[0] to float
|
|
||||||
|
|
||||||
; calculate b * a[0]
|
|
||||||
%8 = fmul float %4, %7
|
|
||||||
%9 = fptosi float %8 to i32
|
|
||||||
|
|
||||||
; store to a[1]
|
|
||||||
%10 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 1 ;a[1]
|
|
||||||
store i32 %9, i32* %10, align 4;
|
|
||||||
%11 = load i32, i32* %10, align 4
|
|
||||||
|
|
||||||
; return a[1]
|
|
||||||
ret i32 %11
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
; 中间代码头部尾部参考clang -S -emit-llvm 生成结果
|
|
||||||
|
|
||||||
; ModuleID = 'func_test.c'
|
|
||||||
source_filename = "func_test.c"
|
|
||||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
||||||
target triple = "x86_64-pc-linux-gnu"
|
|
||||||
|
|
||||||
define dso_local i32 @add(i32 %0, i32 %1) #0 {
|
|
||||||
%3 = alloca i32, align 4
|
|
||||||
store i32 %0, i32* %3, align 4 ; alloca a
|
|
||||||
|
|
||||||
%4 = alloca i32, align 4
|
|
||||||
store i32 %1, i32* %4, align 4 ; alloca b
|
|
||||||
|
|
||||||
%5 = load i32, i32* %3, align 4
|
|
||||||
%6 = load i32, i32* %4, align 4
|
|
||||||
%7 = add nsw i32 %5, %6 ; a+b
|
|
||||||
%8 = sub nsw i32 %7, 1 ; a+b-1
|
|
||||||
ret i32 %8 ; return a+b-1
|
|
||||||
}
|
|
||||||
|
|
||||||
define dso_local i32 @main() #0 {
|
|
||||||
%1 = alloca i32, align 4
|
|
||||||
%2 = alloca i32, align 4
|
|
||||||
%3 = alloca i32, align 4
|
|
||||||
|
|
||||||
store i32 3, i32* %1, align 4 ; a=3
|
|
||||||
store i32 2, i32* %2, align 4 ; b=2
|
|
||||||
store i32 5, i32* %3, align 4 ; c=5
|
|
||||||
|
|
||||||
|
|
||||||
%4 = load i32, i32* %1, align 4
|
|
||||||
%5 = load i32, i32* %2, align 4
|
|
||||||
%6 = load i32, i32* %3, align 4
|
|
||||||
|
|
||||||
%7 = call i32 @add(i32 %4, i32 %5) ; add(a, b)
|
|
||||||
%8 = add nsw i32 %6, %7 ; c+add(a,b)
|
|
||||||
ret i32 %8
|
|
||||||
}
|
|
||||||
|
|
||||||
attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
|
||||||
|
|
||||||
!llvm.module.flags = !{!0, !1, !2, !3, !4}
|
|
||||||
!llvm.ident = !{!5}
|
|
||||||
|
|
||||||
!0 = !{i32 1, !"wchar_size", i32 4}
|
|
||||||
!1 = !{i32 7, !"PIC Level", i32 2}
|
|
||||||
!2 = !{i32 7, !"PIE Level", i32 2}
|
|
||||||
!3 = !{i32 7, !"uwtable", i32 1}
|
|
||||||
!4 = !{i32 7, !"frame-pointer", i32 2}
|
|
||||||
!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"}
|
|
@ -1,11 +0,0 @@
|
|||||||
@a = common global i32 0, align 4
|
|
||||||
define i32 @main() #0 {
|
|
||||||
store i32 10, i32* @a, align 4
|
|
||||||
%1 = load i32, i32* @a, align 4
|
|
||||||
%2 = icmp sgt i32 %1, 0
|
|
||||||
br i1 %2, label %3, label %4
|
|
||||||
3:
|
|
||||||
ret i32 %1
|
|
||||||
4:
|
|
||||||
ret i32 0
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
int main(){
|
|
||||||
float b = 1.8;
|
|
||||||
int a[2] = {2};
|
|
||||||
a[1] = a[0] * b;
|
|
||||||
return a[1];
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
int add(int a,int b){
|
|
||||||
return (a+b-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
int a;
|
|
||||||
int b;
|
|
||||||
int c;
|
|
||||||
a=3;
|
|
||||||
b=2;
|
|
||||||
c = 5;
|
|
||||||
return c + add(a,b);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
int a;
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
a = 10;
|
|
||||||
if( a>0 ){
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
int a;
|
|
||||||
int b;
|
|
||||||
int main(){
|
|
||||||
b=0;
|
|
||||||
a=3;
|
|
||||||
while(a>0){
|
|
||||||
b = b+a;
|
|
||||||
a = a-1;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
project(task2)
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.5)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -Wall -g -pedantic")
|
|
||||||
|
|
||||||
set(SYSYF_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../)
|
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
|
|
||||||
# include generated files in project environment
|
|
||||||
include_directories(${SYSYF_SOURCE_DIR}include)
|
|
||||||
include_directories(${SYSYF_SOURCE_DIR}include/SysYFIR)
|
|
||||||
add_subdirectory(${SYSYF_SOURCE_DIR}src/SysYFIR src/SysYFIR)
|
|
||||||
|
|
||||||
add_subdirectory(demo)
|
|
||||||
add_subdirectory(cpp)
|
|
@ -1,36 +0,0 @@
|
|||||||
add_executable(
|
|
||||||
assign_generator
|
|
||||||
assign_gen.cpp
|
|
||||||
)
|
|
||||||
target_link_libraries(
|
|
||||||
assign_generator
|
|
||||||
IRLib
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(
|
|
||||||
func_generator
|
|
||||||
func_gen.cpp
|
|
||||||
)
|
|
||||||
target_link_libraries(
|
|
||||||
func_generator
|
|
||||||
IRLib
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(
|
|
||||||
if_generator
|
|
||||||
if_gen.cpp
|
|
||||||
)
|
|
||||||
target_link_libraries(
|
|
||||||
if_generator
|
|
||||||
IRLib
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(
|
|
||||||
while_generator
|
|
||||||
while_gen.cpp
|
|
||||||
)
|
|
||||||
target_link_libraries(
|
|
||||||
while_generator
|
|
||||||
IRLib
|
|
||||||
)
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
#include "BasicBlock.h"
|
|
||||||
#include "Constant.h"
|
|
||||||
#include "Function.h"
|
|
||||||
#include "IRStmtBuilder.h"
|
|
||||||
#include "Module.h"
|
|
||||||
#include "Type.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // 输出行号的简单示例
|
|
||||||
#else
|
|
||||||
#define DEBUG_OUTPUT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CONST_INT(num) \
|
|
||||||
ConstantInt::create(num, module)
|
|
||||||
|
|
||||||
#define CONST_FP(num) \
|
|
||||||
ConstantFloat::create(num, module)
|
|
||||||
|
|
||||||
using namespace SysYF::IR;
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
auto module = Module::create("Assign code");
|
|
||||||
auto builder = IRStmtBuilder::create(nullptr, module);
|
|
||||||
SysYF::Ptr<Type> Int32Type = Type::get_int32_type(module);
|
|
||||||
SysYF::Ptr<Type> FloatType = Type::get_float_type(module);
|
|
||||||
|
|
||||||
// main function
|
|
||||||
auto mainFun = Function::create(FunctionType::create(Int32Type, {}),
|
|
||||||
"main", module);
|
|
||||||
auto bb = BasicBlock::create(module, "entry", mainFun);
|
|
||||||
builder->set_insert_point(bb);
|
|
||||||
auto retAlloca = builder->create_alloca(Int32Type);
|
|
||||||
|
|
||||||
// b = 1.8
|
|
||||||
auto bAlloca = builder->create_alloca(FloatType);
|
|
||||||
builder->create_store(CONST_FP(1.8), bAlloca);
|
|
||||||
|
|
||||||
// a[2] = {2}
|
|
||||||
auto arrayType_a = ArrayType::get(Int32Type, 2);
|
|
||||||
auto aAlloca = builder->create_alloca(arrayType_a);
|
|
||||||
auto a0Gep = builder->create_gep(aAlloca, {CONST_INT(0), CONST_INT(0)});
|
|
||||||
builder->create_store(CONST_INT(2), a0Gep);
|
|
||||||
|
|
||||||
// a[0] * b
|
|
||||||
auto a0Load = builder->create_load(a0Gep);
|
|
||||||
auto a0Float = builder->create_sitofp(a0Load, FloatType);
|
|
||||||
auto bLoad = builder->create_load(FloatType, bAlloca);
|
|
||||||
auto a1res = builder->create_fmul(a0Float, bLoad);
|
|
||||||
|
|
||||||
// store to a[1]
|
|
||||||
auto a1res_int = builder->create_fptosi(a1res, Int32Type);
|
|
||||||
auto a1Gep = builder->create_gep(aAlloca, {CONST_INT(0), CONST_INT(1)});
|
|
||||||
builder->create_store(a1res_int, a1Gep);
|
|
||||||
|
|
||||||
// ret
|
|
||||||
builder->create_store(a1res_int, retAlloca);
|
|
||||||
auto retLoad = builder->create_load(retAlloca);
|
|
||||||
builder->create_ret(retLoad);
|
|
||||||
|
|
||||||
std::cout << module->print();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
#include "BasicBlock.h"
|
|
||||||
#include "Constant.h"
|
|
||||||
#include "Function.h"
|
|
||||||
#include "IRStmtBuilder.h"
|
|
||||||
#include "Module.h"
|
|
||||||
#include "Type.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#ifdef DEBUG // 用于调试信息,大家可以在编译过程中通过" -DDEBUG"来开启这一选项
|
|
||||||
#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // 输出行号的简单示例
|
|
||||||
#else
|
|
||||||
#define DEBUG_OUTPUT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CONST_INT(num) \
|
|
||||||
ConstantInt::create(num, module)
|
|
||||||
|
|
||||||
#define CONST_FP(num) \
|
|
||||||
ConstantFloat::create(num, module) // 得到常数值的表示,方便后面多次用到
|
|
||||||
|
|
||||||
using namespace SysYF::IR;
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
auto module = Module::create("SysYF code"); // module name是什么无关紧要
|
|
||||||
auto builder = IRStmtBuilder::create(nullptr, module);
|
|
||||||
SysYF::Ptr<Type> Int32Type = Type::get_int32_type(module);
|
|
||||||
|
|
||||||
// add(a, b)
|
|
||||||
// 函数参数类型的vector
|
|
||||||
std::vector<SysYF::Ptr<Type>> Ints(2, Int32Type);
|
|
||||||
|
|
||||||
//通过返回值类型与参数类型列表得到函数类型
|
|
||||||
auto addFunTy = FunctionType::create(Int32Type, Ints);
|
|
||||||
|
|
||||||
// 由函数类型得到函数
|
|
||||||
auto addFun = Function::create(addFunTy,
|
|
||||||
"add", module);
|
|
||||||
|
|
||||||
// BB的名字在生成中无所谓,但是可以方便阅读
|
|
||||||
auto bb = BasicBlock::create(module, "entry", addFun);
|
|
||||||
|
|
||||||
builder->set_insert_point(bb); // 一个BB的开始,将当前插入指令点的位置设在bb
|
|
||||||
|
|
||||||
auto retAlloca = builder->create_alloca(Int32Type); // 在内存中分配返回值的位置
|
|
||||||
auto aAlloca = builder->create_alloca(Int32Type); // 在内存中分配参数a的位置
|
|
||||||
auto bAlloca = builder->create_alloca(Int32Type); // 在内存中分配参数b的位置
|
|
||||||
|
|
||||||
std::vector<SysYF::Ptr<Value>> args; // 获取add函数的形参,通过Function中的iterator
|
|
||||||
for (auto arg = addFun->arg_begin(); arg != addFun->arg_end(); arg++) {
|
|
||||||
args.push_back(*arg); // * 号运算符是从迭代器中取出迭代器当前指向的元素
|
|
||||||
}
|
|
||||||
|
|
||||||
builder->create_store(args[0], aAlloca); // store参数a
|
|
||||||
builder->create_store(args[1], bAlloca); // store参数b
|
|
||||||
|
|
||||||
auto aLoad = builder->create_load(aAlloca); // load参数a
|
|
||||||
auto bLoad = builder->create_load(bAlloca); // load参数b
|
|
||||||
|
|
||||||
// a+b
|
|
||||||
auto add = builder->create_iadd(aLoad, bLoad);
|
|
||||||
|
|
||||||
// a+b-1
|
|
||||||
auto sub = builder->create_isub(add, CONST_INT(1));
|
|
||||||
|
|
||||||
builder->create_store(sub, retAlloca);
|
|
||||||
auto retLoad = builder->create_load(retAlloca);
|
|
||||||
builder->create_ret(retLoad);
|
|
||||||
builder->create_ret(retLoad);
|
|
||||||
|
|
||||||
// main函数
|
|
||||||
auto mainFun = Function::create(FunctionType::create(Int32Type, {}),
|
|
||||||
"main", module);
|
|
||||||
bb = BasicBlock::create(module, "entry", mainFun);
|
|
||||||
// BasicBlock的名字在生成中无所谓,但是可以方便阅读
|
|
||||||
builder->set_insert_point(bb);
|
|
||||||
|
|
||||||
retAlloca = builder->create_alloca(Int32Type);
|
|
||||||
|
|
||||||
// int a;
|
|
||||||
auto a = builder->create_alloca(Int32Type);
|
|
||||||
|
|
||||||
// int b;
|
|
||||||
auto b = builder->create_alloca(Int32Type);
|
|
||||||
|
|
||||||
// int c;
|
|
||||||
auto c = builder->create_alloca(Int32Type);
|
|
||||||
|
|
||||||
// a = 3;
|
|
||||||
builder->create_store(CONST_INT(3), a);
|
|
||||||
|
|
||||||
// b = 2;
|
|
||||||
builder->create_store(CONST_INT(2), b);
|
|
||||||
|
|
||||||
// c = 5;
|
|
||||||
builder->create_store(CONST_INT(5), c);
|
|
||||||
|
|
||||||
// tmp = add(a, b);
|
|
||||||
aLoad = builder->create_load(a);
|
|
||||||
bLoad = builder->create_load(b);
|
|
||||||
auto tmp = builder->create_call(addFun, {aLoad, bLoad});
|
|
||||||
|
|
||||||
// ret = c + tmp;
|
|
||||||
auto cLoad = builder->create_load(c);
|
|
||||||
auto ret = builder->create_iadd(cLoad, tmp);
|
|
||||||
builder->create_store(ret, retAlloca);
|
|
||||||
retLoad = builder->create_load(retAlloca);
|
|
||||||
builder->create_ret(retLoad);
|
|
||||||
|
|
||||||
std::cout << module->print();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
#include "BasicBlock.h"
|
|
||||||
#include "Constant.h"
|
|
||||||
#include "Function.h"
|
|
||||||
#include "IRStmtBuilder.h"
|
|
||||||
#include "Module.h"
|
|
||||||
#include "Type.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // 输出行号的简单示例
|
|
||||||
#else
|
|
||||||
#define DEBUG_OUTPUT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CONST_INT(num) \
|
|
||||||
ConstantInt::create(num, module)
|
|
||||||
|
|
||||||
#define CONST_FP(num) \
|
|
||||||
ConstantFloat::create(num, module)
|
|
||||||
|
|
||||||
using namespace SysYF::IR;
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
auto module = Module::create("If code");
|
|
||||||
auto builder = IRStmtBuilder::create(nullptr, module);
|
|
||||||
SysYF::Ptr<Type> Int32Type = Type::get_int32_type(module);
|
|
||||||
SysYF::Ptr<Type> FloatType = Type::get_float_type(module);
|
|
||||||
|
|
||||||
auto zero_initializer = ConstantZero::create(Int32Type, module);
|
|
||||||
auto a = GlobalVariable::create("a", module, Int32Type, false, zero_initializer);
|
|
||||||
|
|
||||||
// main function
|
|
||||||
auto mainFun = Function::create(FunctionType::create(Int32Type, {}),
|
|
||||||
"main", module);
|
|
||||||
auto bb = BasicBlock::create(module, "entry", mainFun);
|
|
||||||
builder->set_insert_point(bb);
|
|
||||||
auto retAlloca = builder->create_alloca(Int32Type);
|
|
||||||
|
|
||||||
// store 10 to a
|
|
||||||
builder->create_store(CONST_INT(10), a);
|
|
||||||
auto aValue = builder->create_load(a);
|
|
||||||
|
|
||||||
// if(a > 0)
|
|
||||||
auto icmp = builder->create_icmp_gt(aValue, CONST_INT(0));
|
|
||||||
auto trueBB = BasicBlock::create(module, "trueBB_if", mainFun); // true分支
|
|
||||||
auto falseBB = BasicBlock::create(module, "falseBB_if", mainFun); // false分支
|
|
||||||
builder->create_cond_br(icmp, trueBB, falseBB); // 条件BR
|
|
||||||
|
|
||||||
// if true return a
|
|
||||||
builder->set_insert_point(trueBB);
|
|
||||||
builder->create_ret(aValue);
|
|
||||||
|
|
||||||
// if false return 0
|
|
||||||
builder->set_insert_point(falseBB);
|
|
||||||
builder->create_ret(CONST_INT(0));
|
|
||||||
|
|
||||||
std::cout << module->print();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
#include "BasicBlock.h"
|
|
||||||
#include "Constant.h"
|
|
||||||
#include "Function.h"
|
|
||||||
#include "IRStmtBuilder.h"
|
|
||||||
#include "Module.h"
|
|
||||||
#include "Type.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#ifdef DEBUG // 用于调试信息,大家可以在编译过程中通过" -DDEBUG"来开启这一选项
|
|
||||||
#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // 输出行号的简单示例
|
|
||||||
#else
|
|
||||||
#define DEBUG_OUTPUT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CONST_INT(num) \
|
|
||||||
ConstantInt::create(num, module)
|
|
||||||
|
|
||||||
#define CONST_FP(num) \
|
|
||||||
ConstantFloat::create(num, module) // 得到常数值的表示,方便后面多次用到
|
|
||||||
|
|
||||||
using namespace SysYF::IR;
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
auto module = Module::create("SysYF code"); // module name是什么无关紧要
|
|
||||||
auto builder = IRStmtBuilder::create(nullptr, module);
|
|
||||||
SysYF::Ptr<Type> Int32Type = Type::get_int32_type(module);
|
|
||||||
|
|
||||||
// int a;
|
|
||||||
auto a = GlobalVariable::create("a", module, Int32Type, false, CONST_INT(0));
|
|
||||||
|
|
||||||
// int b;
|
|
||||||
auto b = GlobalVariable::create("b", module, Int32Type, false, CONST_INT(0));
|
|
||||||
|
|
||||||
// main函数
|
|
||||||
auto mainFun = Function::create(FunctionType::create(Int32Type, {}),
|
|
||||||
"main", module);
|
|
||||||
auto bb = BasicBlock::create(module, "entry", mainFun);
|
|
||||||
// BasicBlock的名字在生成中无所谓,但是可以方便阅读
|
|
||||||
builder->set_insert_point(bb);
|
|
||||||
|
|
||||||
auto retAlloca = builder->create_alloca(Int32Type);
|
|
||||||
|
|
||||||
// b=0;
|
|
||||||
builder->create_store(CONST_INT(0), b);
|
|
||||||
|
|
||||||
// a = 3;
|
|
||||||
builder->create_store(CONST_INT(3), a);
|
|
||||||
|
|
||||||
// whileBBs
|
|
||||||
auto condBB = BasicBlock::create(module, "condBB_while", mainFun);
|
|
||||||
auto trueBB = BasicBlock::create(module, "trueBB_while", mainFun);
|
|
||||||
auto falseBB = BasicBlock::create(module, "falseBB_while", mainFun);
|
|
||||||
|
|
||||||
builder->create_br(condBB);
|
|
||||||
|
|
||||||
// condBB
|
|
||||||
builder->set_insert_point(condBB);
|
|
||||||
auto aLoad = builder->create_load(a);
|
|
||||||
auto icmp = builder->create_icmp_gt(aLoad, CONST_INT(0));
|
|
||||||
builder->create_cond_br(icmp, trueBB, falseBB);
|
|
||||||
|
|
||||||
// trueBB
|
|
||||||
builder->set_insert_point(trueBB);
|
|
||||||
aLoad = builder->create_load(a);
|
|
||||||
auto bLoad = builder->create_load(b);
|
|
||||||
auto add = builder->create_iadd(bLoad, aLoad);
|
|
||||||
builder->create_store(add, b);
|
|
||||||
auto sub = builder->create_isub(aLoad, CONST_INT(1));
|
|
||||||
builder->create_store(sub, a);
|
|
||||||
builder->create_br(condBB);
|
|
||||||
|
|
||||||
// falseBB
|
|
||||||
builder->set_insert_point(falseBB);
|
|
||||||
bLoad = builder->create_load(b);
|
|
||||||
builder->create_store(bLoad, retAlloca);
|
|
||||||
auto retLoad = builder->create_load(retAlloca);
|
|
||||||
builder->create_ret(retLoad);
|
|
||||||
|
|
||||||
std::cout << module->print();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
add_executable(
|
|
||||||
go_upstairs_generator
|
|
||||||
go_upstairs_gen.cpp
|
|
||||||
)
|
|
||||||
target_link_libraries(
|
|
||||||
go_upstairs_generator
|
|
||||||
IRLib
|
|
||||||
)
|
|
@ -1,28 +0,0 @@
|
|||||||
int num[2] = {4, 8};
|
|
||||||
int x[1];
|
|
||||||
int n;
|
|
||||||
int tmp = 1;
|
|
||||||
|
|
||||||
int climbStairs(int n) {
|
|
||||||
if(n < 4)
|
|
||||||
return n;
|
|
||||||
int dp[10];
|
|
||||||
dp[0] = 0;
|
|
||||||
dp[1] = 1;
|
|
||||||
dp[2] = 2;
|
|
||||||
int i;
|
|
||||||
i = 3;
|
|
||||||
while(i<n+1){
|
|
||||||
dp[i] = dp[i-1] + dp[i-2];
|
|
||||||
i = i + 1;
|
|
||||||
}
|
|
||||||
return dp[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
int res;
|
|
||||||
n=num[0];
|
|
||||||
x[0] = num[tmp];
|
|
||||||
res = climbStairs(n + tmp);
|
|
||||||
return res - x[0];
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
int main(){
|
|
||||||
float b = 1.8;
|
|
||||||
int a[2] = {2};
|
|
||||||
a[1] = a[0] * b;
|
|
||||||
return a[1];
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
int add(int a,int b){
|
|
||||||
return (a+b-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
int a;
|
|
||||||
int b;
|
|
||||||
int c;
|
|
||||||
a=3;
|
|
||||||
b=2;
|
|
||||||
c = 5;
|
|
||||||
return c + add(a,b);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
int a;
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
a = 10;
|
|
||||||
if( a>0 ){
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
int a;
|
|
||||||
int b;
|
|
||||||
int main(){
|
|
||||||
b=0;
|
|
||||||
a=3;
|
|
||||||
while(a>0){
|
|
||||||
b = b+a;
|
|
||||||
a = a-1;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
@ -1,93 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import subprocess
|
|
||||||
import os
|
|
||||||
|
|
||||||
IRBuild_ptn = '"{}" "-emit-ir" "-o" "{}" "{}"'
|
|
||||||
ExeGen_ptn = '"clang" "{}" "-o" "{}" "{}" "../../lib/lib.c"'
|
|
||||||
Exe_ptn = '"{}"'
|
|
||||||
|
|
||||||
def eval(EXE_PATH, TEST_BASE_PATH, optimization):
|
|
||||||
print('===========TEST START===========')
|
|
||||||
print('now in {}'.format(TEST_BASE_PATH))
|
|
||||||
dir_succ = True
|
|
||||||
for case in testcases:
|
|
||||||
print('Case %s:' % case, end='')
|
|
||||||
TEST_PATH = TEST_BASE_PATH + case
|
|
||||||
SY_PATH = TEST_BASE_PATH + case + '.sy'
|
|
||||||
LL_PATH = TEST_BASE_PATH + case + '.ll'
|
|
||||||
INPUT_PATH = TEST_BASE_PATH + case + '.in'
|
|
||||||
OUTPUT_PATH = TEST_BASE_PATH + case + '.out'
|
|
||||||
need_input = testcases[case]
|
|
||||||
|
|
||||||
IRBuild_result = subprocess.run(IRBuild_ptn.format(EXE_PATH, LL_PATH, SY_PATH), shell=True, stderr=subprocess.PIPE)
|
|
||||||
if IRBuild_result.returncode == 0:
|
|
||||||
input_option = None
|
|
||||||
if need_input:
|
|
||||||
with open(INPUT_PATH, "rb") as fin:
|
|
||||||
input_option = fin.read()
|
|
||||||
|
|
||||||
try:
|
|
||||||
subprocess.run(ExeGen_ptn.format(optimization, TEST_PATH, LL_PATH), shell=True, stderr=subprocess.PIPE)
|
|
||||||
result = subprocess.run(Exe_ptn.format(TEST_PATH), shell=True, input=input_option, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
out = result.stdout.split(b'\n')
|
|
||||||
if result.returncode != b'':
|
|
||||||
out.append(str(result.returncode).encode())
|
|
||||||
for i in range(len(out)-1, -1, -1):
|
|
||||||
out[i] = out[i].strip(b'\r')
|
|
||||||
if out[i] == b'':
|
|
||||||
out.remove(b'')
|
|
||||||
case_succ = True
|
|
||||||
with open(OUTPUT_PATH, "rb") as fout:
|
|
||||||
print(out[i])
|
|
||||||
i = 0
|
|
||||||
for line in fout.readlines():
|
|
||||||
line = line.strip(b'\r').strip(b'\n')
|
|
||||||
if line == '':
|
|
||||||
continue
|
|
||||||
if out[i] != line:
|
|
||||||
dir_succ = False
|
|
||||||
case_succ = False
|
|
||||||
i = i + 1
|
|
||||||
if case_succ:
|
|
||||||
print('\t\033[32mPass\033[0m')
|
|
||||||
else:
|
|
||||||
print('\t\033[31mWrong Answer\033[0m')
|
|
||||||
except Exception as _:
|
|
||||||
dir_succ = False
|
|
||||||
print(_, end='')
|
|
||||||
print('\t\033[31mCodeGen or CodeExecute Fail\033[0m')
|
|
||||||
finally:
|
|
||||||
subprocess.call(["rm", "-rf", TEST_PATH, TEST_PATH])
|
|
||||||
subprocess.call(["rm", "-rf", TEST_PATH, TEST_PATH + ".o"])
|
|
||||||
subprocess.call(["rm", "-rf", TEST_PATH, TEST_PATH + ".ll"])
|
|
||||||
|
|
||||||
else:
|
|
||||||
dir_succ = False
|
|
||||||
print('\t\033[31mIRBuild Fail\033[0m')
|
|
||||||
if dir_succ:
|
|
||||||
print('\t\033[32mSuccess\033[0m in dir {}'.format(TEST_BASE_PATH))
|
|
||||||
else:
|
|
||||||
print('\t\033[31mFail\033[0m in dir {}'.format(TEST_BASE_PATH))
|
|
||||||
|
|
||||||
print('============TEST END============')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
# you can only modify this to add your testcase
|
|
||||||
TEST_DIRS = [
|
|
||||||
'./test/',
|
|
||||||
]
|
|
||||||
# you can only modify this to add your testcase
|
|
||||||
|
|
||||||
optimization = "-O0" # -O0 -O1 -O2 -O3 -O4(currently = -O3) -Ofast
|
|
||||||
for TEST_BASE_PATH in TEST_DIRS:
|
|
||||||
testcases = {} # { name: need_input }
|
|
||||||
EXE_PATH = os.path.abspath('../../build/SysYFCompiler')
|
|
||||||
testcase_list = list(map(lambda x: x.split('.'), os.listdir(TEST_BASE_PATH)))
|
|
||||||
testcase_list.sort()
|
|
||||||
for i in range(len(testcase_list)):
|
|
||||||
testcases[testcase_list[i][0]] = False
|
|
||||||
for i in range(len(testcase_list)):
|
|
||||||
testcases[testcase_list[i][0]] = testcases[testcase_list[i][0]] | (testcase_list[i][1] == 'in')
|
|
||||||
eval(EXE_PATH, TEST_BASE_PATH, optimization=optimization)
|
|
@ -1 +0,0 @@
|
|||||||
0
|
|
@ -1,3 +0,0 @@
|
|||||||
int main(){
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
29
|
|
@ -1,8 +0,0 @@
|
|||||||
int a,b;
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
a=10;
|
|
||||||
b=5;
|
|
||||||
int c=a*2+b*1.1+3.6;
|
|
||||||
return c;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
21
|
|
@ -1,5 +0,0 @@
|
|||||||
int main() {
|
|
||||||
int a = 10;
|
|
||||||
;
|
|
||||||
return a * 2 + 1;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
0
|
|
@ -1,4 +0,0 @@
|
|||||||
int a[10];
|
|
||||||
int main(){
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
0
|
|
@ -1,5 +0,0 @@
|
|||||||
int a[10];
|
|
||||||
int main(){
|
|
||||||
a[0]=1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
4
|
|
@ -1,5 +0,0 @@
|
|||||||
const int x=4;
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
return x;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
8
|
|
@ -1,7 +0,0 @@
|
|||||||
const int a[5]={0,1,2,3,4};
|
|
||||||
const int b = 3;
|
|
||||||
float c = a[b + 1];
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
return a[4] + c;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
4
|
|
@ -1,8 +0,0 @@
|
|||||||
int defn(){
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
int a=defn();
|
|
||||||
return a;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
5
|
|
@ -1,13 +0,0 @@
|
|||||||
int a,b,c;
|
|
||||||
|
|
||||||
void add(int a,int b){
|
|
||||||
c=a+b;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
a=3;
|
|
||||||
b=2;
|
|
||||||
add(a,b);
|
|
||||||
return c;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
1
|
|
@ -1,9 +0,0 @@
|
|||||||
int a;
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
a = 10;
|
|
||||||
if( a>0 ){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
1
|
|
@ -1,10 +0,0 @@
|
|||||||
int a;
|
|
||||||
int main(){
|
|
||||||
a = 10;
|
|
||||||
if( a>0 ){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
6
|
|
@ -1,11 +0,0 @@
|
|||||||
int a;
|
|
||||||
int b;
|
|
||||||
int main(){
|
|
||||||
b=0;
|
|
||||||
a=3;
|
|
||||||
while(a>0){
|
|
||||||
b = b+a;
|
|
||||||
a = a-1;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
5
|
|
@ -1,9 +0,0 @@
|
|||||||
int main(){
|
|
||||||
int a=10;
|
|
||||||
while(a>0){
|
|
||||||
a=a-1;
|
|
||||||
if(a==5)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
5
|
|
@ -1,11 +0,0 @@
|
|||||||
int main(){
|
|
||||||
int a=10;
|
|
||||||
while(a>0){
|
|
||||||
if(a>5){
|
|
||||||
a=a-1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
10
|
|
@ -1 +0,0 @@
|
|||||||
10
|
|
@ -1,5 +0,0 @@
|
|||||||
int main(){
|
|
||||||
int a;
|
|
||||||
a = getint();
|
|
||||||
return a;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
5
|
|
@ -1,23 +0,0 @@
|
|||||||
int a;
|
|
||||||
|
|
||||||
int myFunc(int a, int b, int c) {
|
|
||||||
a = 2;
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
c = 0;
|
|
||||||
if (c != 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (b > 0) {
|
|
||||||
b = b - 1;
|
|
||||||
}
|
|
||||||
return (a)+(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
a = (3);
|
|
||||||
int b;
|
|
||||||
b = myFunc(1, 2, 1);
|
|
||||||
return ((a+b));
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
3 2
|
|
@ -1 +0,0 @@
|
|||||||
0
|
|
@ -1,12 +0,0 @@
|
|||||||
int a;
|
|
||||||
int b;
|
|
||||||
int main(){
|
|
||||||
a = getint();
|
|
||||||
b = getint();
|
|
||||||
if ( a == b ){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
8
|
|
@ -1,17 +0,0 @@
|
|||||||
const int a = 5;
|
|
||||||
int b;
|
|
||||||
|
|
||||||
int my_sum(int x, float y){
|
|
||||||
b = a + x - y;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
int a = 7;
|
|
||||||
{
|
|
||||||
const float a = 3.3;
|
|
||||||
my_sum(a, a);
|
|
||||||
}
|
|
||||||
my_sum(a, b);
|
|
||||||
return b;
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
4
|
|
||||||
20
|
|
@ -1 +0,0 @@
|
|||||||
4
|
|
@ -1,34 +0,0 @@
|
|||||||
int n;
|
|
||||||
|
|
||||||
int gcd(int m,int n)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if(m<n) { t=m;m=n;n=t; }
|
|
||||||
|
|
||||||
r=m%n;
|
|
||||||
|
|
||||||
while(r!=0)
|
|
||||||
{
|
|
||||||
m=n;
|
|
||||||
n=r;
|
|
||||||
r=m%n;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
//newline=10;
|
|
||||||
int i;
|
|
||||||
int m;
|
|
||||||
//m = 1478;
|
|
||||||
//int t;
|
|
||||||
i=getint();
|
|
||||||
m=getint();
|
|
||||||
|
|
||||||
return gcd(i,m);
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
4
|
|
||||||
4
|
|
||||||
7
|
|
||||||
3
|
|
||||||
9
|
|
@ -1,5 +0,0 @@
|
|||||||
1 2, 1 3, 2 3, 1 2, 3 1, 3 2, 1 2, 1 3, 2 3, 2 1, 3 1, 2 3, 1 2, 1 3, 2 3,
|
|
||||||
1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3,
|
|
||||||
1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3,
|
|
||||||
1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 3 1, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 1 2, 3 2, 3 1, 2 1, 3 2, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3, 2 1, 3 2, 3 1, 2 1, 2 3, 1 3, 1 2, 3 2, 1 3, 2 1, 2 3, 1 3,
|
|
||||||
0
|
|
@ -1,27 +0,0 @@
|
|||||||
|
|
||||||
void move(int x, int y)
|
|
||||||
{
|
|
||||||
putint(x); putch(32); putint(y); putch(44); putch(32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hanoi(int n, int one, int two, int three)
|
|
||||||
{
|
|
||||||
if (n == 1)
|
|
||||||
move(one, three);
|
|
||||||
else {
|
|
||||||
hanoi(n - 1, one, three, two);
|
|
||||||
move(one, three);
|
|
||||||
hanoi(n - 1, two, one, three);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int n = getint();
|
|
||||||
while (n > 0) {
|
|
||||||
hanoi(getint(), 1, 2, 3);
|
|
||||||
putch(10);
|
|
||||||
n = n - 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 30 KiB |
@ -1,330 +0,0 @@
|
|||||||
#ifndef _SYSYF_SYNTAX_TREE_H_
|
|
||||||
#define _SYSYF_SYNTAX_TREE_H_
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "location.hh"
|
|
||||||
#include "internal_types.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace SyntaxTree
|
|
||||||
{
|
|
||||||
|
|
||||||
using Position = yy::location;
|
|
||||||
|
|
||||||
// Enumerations
|
|
||||||
enum class Type
|
|
||||||
{
|
|
||||||
INT = 0,
|
|
||||||
VOID,
|
|
||||||
STRING,
|
|
||||||
BOOL,
|
|
||||||
FLOAT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class BinOp
|
|
||||||
{
|
|
||||||
PLUS = 0,
|
|
||||||
MINUS,
|
|
||||||
MULTIPLY,
|
|
||||||
DIVIDE,
|
|
||||||
MODULO
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class UnaryOp
|
|
||||||
{
|
|
||||||
PLUS = 0,
|
|
||||||
MINUS
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class UnaryCondOp
|
|
||||||
{
|
|
||||||
NOT = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class BinaryCondOp
|
|
||||||
{
|
|
||||||
LT = 0,
|
|
||||||
LTE,
|
|
||||||
GT,
|
|
||||||
GTE,
|
|
||||||
EQ,
|
|
||||||
NEQ,
|
|
||||||
LAND,
|
|
||||||
LOR
|
|
||||||
};
|
|
||||||
|
|
||||||
// Forward declaration
|
|
||||||
struct Node;
|
|
||||||
struct Assembly;
|
|
||||||
struct GlobalDef;
|
|
||||||
struct FuncDef;
|
|
||||||
|
|
||||||
struct Expr;
|
|
||||||
struct CondExpr;
|
|
||||||
struct AddExpr;
|
|
||||||
struct BinaryExpr;
|
|
||||||
struct BinaryCondExpr;
|
|
||||||
struct UnaryCondExpr;
|
|
||||||
struct UnaryExpr;
|
|
||||||
struct LVal;
|
|
||||||
struct Literal;
|
|
||||||
|
|
||||||
struct Stmt;
|
|
||||||
struct VarDef;
|
|
||||||
struct AssignStmt;
|
|
||||||
struct FuncCallStmt;
|
|
||||||
struct ReturnStmt;
|
|
||||||
struct BlockStmt;
|
|
||||||
struct EmptyStmt;
|
|
||||||
struct ExprStmt;
|
|
||||||
|
|
||||||
struct FuncParam;
|
|
||||||
struct FuncFParamList;
|
|
||||||
|
|
||||||
struct IfStmt;
|
|
||||||
struct WhileStmt;
|
|
||||||
struct BreakStmt;
|
|
||||||
struct ContinueStmt;
|
|
||||||
struct InitVal;
|
|
||||||
|
|
||||||
class Visitor;
|
|
||||||
|
|
||||||
// Virtual base of all kinds of syntax tree nodes.
|
|
||||||
struct Node
|
|
||||||
{
|
|
||||||
Position loc;
|
|
||||||
// Used in Visitor. Irrelevant to syntax tree generation.
|
|
||||||
virtual void accept(Visitor &visitor) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
//node for initial value
|
|
||||||
struct InitVal: Node{
|
|
||||||
bool isExp;
|
|
||||||
PtrVec<InitVal> elementList;
|
|
||||||
//std::vector<Ptr<InitVal>> elementList;
|
|
||||||
Ptr<Expr> expr;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Root node of an ordinary syntax tree.
|
|
||||||
struct Assembly : Node
|
|
||||||
{
|
|
||||||
PtrVec<GlobalDef> global_defs;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Virtual base of global definitions, function or variable one.
|
|
||||||
struct GlobalDef : virtual Node
|
|
||||||
{
|
|
||||||
void accept(Visitor &visitor) override = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Function definition.
|
|
||||||
struct FuncDef : GlobalDef
|
|
||||||
{
|
|
||||||
Type ret_type;
|
|
||||||
Ptr<FuncFParamList> param_list;
|
|
||||||
std::string name;
|
|
||||||
Ptr<BlockStmt> body;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Virtual base for statements.
|
|
||||||
struct Stmt : virtual Node
|
|
||||||
{
|
|
||||||
void accept(Visitor &visitor) override = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Variable definition. Multiple of this would be both a statement and a global definition; however, itself only
|
|
||||||
// represents a single variable definition.
|
|
||||||
struct VarDef : Stmt, GlobalDef
|
|
||||||
{
|
|
||||||
bool is_constant;
|
|
||||||
Type btype;
|
|
||||||
std::string name;
|
|
||||||
bool is_inited; // This is used to verify `{}`
|
|
||||||
PtrVec<Expr> array_length; // empty for non-array variables
|
|
||||||
Ptr<InitVal> initializers;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Assignment statement.
|
|
||||||
struct AssignStmt : Stmt
|
|
||||||
{
|
|
||||||
Ptr<LVal> target;
|
|
||||||
Ptr<Expr> value;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return statement.
|
|
||||||
struct ReturnStmt : Stmt
|
|
||||||
{
|
|
||||||
Ptr<Expr> ret; // nullptr for void return
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// BlockStmt statement.
|
|
||||||
struct BlockStmt : Stmt
|
|
||||||
{
|
|
||||||
PtrVec<Stmt> body;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Empty statement (aka a single ';').
|
|
||||||
struct EmptyStmt : Stmt
|
|
||||||
{
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ExprStmt : Stmt
|
|
||||||
{
|
|
||||||
Ptr<Expr> exp;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Virtual base of expressions.
|
|
||||||
struct Expr : Node
|
|
||||||
{
|
|
||||||
void accept(Visitor &visitor) override = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CondExpr : Expr
|
|
||||||
{
|
|
||||||
void accept(Visitor &visitor) override = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AddExpr : Expr
|
|
||||||
{
|
|
||||||
void accept(Visitor &visitor) override = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct UnaryCondExpr : CondExpr{
|
|
||||||
UnaryCondOp op;
|
|
||||||
Ptr<Expr> rhs;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BinaryCondExpr : CondExpr{
|
|
||||||
BinaryCondOp op;
|
|
||||||
Ptr<Expr> lhs,rhs;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Expression like `lhs op rhs`.
|
|
||||||
struct BinaryExpr : AddExpr
|
|
||||||
{
|
|
||||||
BinOp op;
|
|
||||||
Ptr<Expr> lhs, rhs;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Expression like `op rhs`.
|
|
||||||
struct UnaryExpr : AddExpr
|
|
||||||
{
|
|
||||||
UnaryOp op;
|
|
||||||
Ptr<Expr> rhs;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Expression like `ident` or `ident[exp]`.
|
|
||||||
struct LVal : AddExpr
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
PtrVec<Expr> array_index; // nullptr if not indexed as array
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Expression constructed by a literal number.
|
|
||||||
struct Literal : AddExpr
|
|
||||||
{
|
|
||||||
Type literal_type;
|
|
||||||
int int_const;
|
|
||||||
// std::string str;
|
|
||||||
double float_const;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Function call statement.
|
|
||||||
struct FuncCallStmt : AddExpr
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
PtrVec<Expr> params;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FuncParam : Node
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
Type param_type;
|
|
||||||
PtrVec<Expr> array_index; // nullptr if not indexed as array
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FuncFParamList : Node
|
|
||||||
{
|
|
||||||
PtrVec<FuncParam> params;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IfStmt : Stmt
|
|
||||||
{
|
|
||||||
Ptr<Expr> cond_exp;
|
|
||||||
Ptr<Stmt> if_statement;
|
|
||||||
Ptr<Stmt> else_statement;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WhileStmt : Stmt
|
|
||||||
{
|
|
||||||
Ptr<Expr> cond_exp;
|
|
||||||
Ptr<Stmt> statement;
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BreakStmt : Stmt
|
|
||||||
{
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ContinueStmt : Stmt
|
|
||||||
{
|
|
||||||
void accept(Visitor &visitor) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Visitor base type
|
|
||||||
class Visitor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void visit(Assembly &node) = 0;
|
|
||||||
virtual void visit(FuncDef &node) = 0;
|
|
||||||
virtual void visit(BinaryExpr &node) = 0;
|
|
||||||
virtual void visit(UnaryExpr &node) = 0;
|
|
||||||
virtual void visit(LVal &node) = 0;
|
|
||||||
virtual void visit(Literal &node) = 0;
|
|
||||||
virtual void visit(ReturnStmt &node) = 0;
|
|
||||||
virtual void visit(VarDef &node) = 0;
|
|
||||||
virtual void visit(AssignStmt &node) = 0;
|
|
||||||
virtual void visit(FuncCallStmt &node) = 0;
|
|
||||||
virtual void visit(BlockStmt &node) = 0;
|
|
||||||
virtual void visit(EmptyStmt &node) = 0;
|
|
||||||
virtual void visit(ExprStmt &node) = 0;
|
|
||||||
virtual void visit(FuncParam &node) = 0;
|
|
||||||
virtual void visit(FuncFParamList &node) = 0;
|
|
||||||
virtual void visit(IfStmt &node) = 0;
|
|
||||||
virtual void visit(WhileStmt &node) = 0;
|
|
||||||
virtual void visit(BreakStmt &node) = 0;
|
|
||||||
virtual void visit(ContinueStmt &node) = 0;
|
|
||||||
virtual void visit(UnaryCondExpr &node) = 0;
|
|
||||||
virtual void visit(BinaryCondExpr &node) = 0;
|
|
||||||
virtual void visit(InitVal &node) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _SYSYF_SYNTAX_TREE_H_
|
|
@ -1,43 +0,0 @@
|
|||||||
#ifndef _SYSYF_SYNTAX_TREE_PRINTER_H_
|
|
||||||
#define _SYSYF_SYNTAX_TREE_PRINTER_H_
|
|
||||||
|
|
||||||
#include "SyntaxTree.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace SyntaxTree
|
|
||||||
{
|
|
||||||
class SyntaxTreePrinter : public SyntaxTree::Visitor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void visit(SyntaxTree::Assembly &node) override;
|
|
||||||
virtual void visit(SyntaxTree::FuncDef &node) override;
|
|
||||||
virtual void visit(SyntaxTree::BinaryExpr &node) override;
|
|
||||||
virtual void visit(SyntaxTree::UnaryExpr &node) override;
|
|
||||||
virtual void visit(SyntaxTree::LVal &node) override;
|
|
||||||
virtual void visit(SyntaxTree::Literal &node) override;
|
|
||||||
virtual void visit(SyntaxTree::ReturnStmt &node) override;
|
|
||||||
virtual void visit(SyntaxTree::VarDef &node) override;
|
|
||||||
virtual void visit(SyntaxTree::AssignStmt &node) override;
|
|
||||||
virtual void visit(SyntaxTree::FuncCallStmt &node) override;
|
|
||||||
virtual void visit(SyntaxTree::BlockStmt &node) override;
|
|
||||||
virtual void visit(SyntaxTree::EmptyStmt &node) override;
|
|
||||||
virtual void visit(SyntaxTree::ExprStmt &node) override;
|
|
||||||
virtual void visit(SyntaxTree::FuncParam &node) override;
|
|
||||||
virtual void visit(SyntaxTree::FuncFParamList &node) override;
|
|
||||||
virtual void visit(SyntaxTree::BinaryCondExpr &node) override;
|
|
||||||
virtual void visit(SyntaxTree::UnaryCondExpr &node) override;
|
|
||||||
virtual void visit(SyntaxTree::IfStmt &node) override;
|
|
||||||
virtual void visit(SyntaxTree::WhileStmt &node) override;
|
|
||||||
virtual void visit(SyntaxTree::BreakStmt &node) override;
|
|
||||||
virtual void visit(SyntaxTree::ContinueStmt &node) override;
|
|
||||||
virtual void visit(SyntaxTree::InitVal &node) override;
|
|
||||||
void print_indent();
|
|
||||||
private:
|
|
||||||
int indent = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _SYSYF_SYNTAX_TREE_PRINTER_H_
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef _SYSYF_ERROR_REPORTER_H_
|
|
||||||
#define _SYSYF_ERROR_REPORTER_H_
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <deque>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
#include "SyntaxTree.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
class ErrorReporter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using Position = SyntaxTree::Position;
|
|
||||||
explicit ErrorReporter(std::ostream &error_stream);
|
|
||||||
|
|
||||||
void error(Position pos, const std::string &msg);
|
|
||||||
void warn(Position pos, const std::string &msg);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void report(Position pos, const std::string &msg, const std::string &prefix);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::ostream &err;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif // _SYSYF_ERROR_REPORTER_H_
|
|
@ -1,225 +0,0 @@
|
|||||||
// -*-C++-*-
|
|
||||||
// FlexLexer.h -- define interfaces for lexical analyzer classes generated
|
|
||||||
// by flex
|
|
||||||
|
|
||||||
// Copyright (c) 1993 The Regents of the University of California.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This code is derived from software contributed to Berkeley by
|
|
||||||
// Kent Williams and Tom Epperly.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions
|
|
||||||
// are met:
|
|
||||||
|
|
||||||
// 1. Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer in the
|
|
||||||
// documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
// Neither the name of the University nor the names of its contributors
|
|
||||||
// may be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
|
|
||||||
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
|
||||||
// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
|
||||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
// PURPOSE.
|
|
||||||
|
|
||||||
// This file defines FlexLexer, an abstract class which specifies the
|
|
||||||
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
|
|
||||||
// which defines a particular lexer class.
|
|
||||||
//
|
|
||||||
// If you want to create multiple lexer classes, you use the -P flag
|
|
||||||
// to rename each yyFlexLexer to some other xxFlexLexer. You then
|
|
||||||
// include <FlexLexer.h> in your other sources once per lexer class:
|
|
||||||
//
|
|
||||||
// #undef yyFlexLexer
|
|
||||||
// #define yyFlexLexer xxFlexLexer
|
|
||||||
// #include <FlexLexer.h>
|
|
||||||
//
|
|
||||||
// #undef yyFlexLexer
|
|
||||||
// #define yyFlexLexer zzFlexLexer
|
|
||||||
// #include <FlexLexer.h>
|
|
||||||
// ...
|
|
||||||
|
|
||||||
#ifndef __FLEX_LEXER_H
|
|
||||||
// Never included before - need to define base class.
|
|
||||||
#define __FLEX_LEXER_H
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
# ifndef FLEX_STD
|
|
||||||
# define FLEX_STD std::
|
|
||||||
# endif
|
|
||||||
|
|
||||||
extern "C++" {
|
|
||||||
|
|
||||||
struct yy_buffer_state;
|
|
||||||
typedef int yy_state_type;
|
|
||||||
|
|
||||||
class FlexLexer {
|
|
||||||
public:
|
|
||||||
virtual ~FlexLexer() { }
|
|
||||||
|
|
||||||
const char* YYText() const { return yytext; }
|
|
||||||
int YYLeng() const { return yyleng; }
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
|
|
||||||
virtual struct yy_buffer_state*
|
|
||||||
yy_create_buffer( FLEX_STD istream* s, int size ) = 0;
|
|
||||||
virtual struct yy_buffer_state*
|
|
||||||
yy_create_buffer( FLEX_STD istream& s, int size ) = 0;
|
|
||||||
virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
|
|
||||||
virtual void yyrestart( FLEX_STD istream* s ) = 0;
|
|
||||||
virtual void yyrestart( FLEX_STD istream& s ) = 0;
|
|
||||||
|
|
||||||
virtual int yylex() = 0;
|
|
||||||
|
|
||||||
// Call yylex with new input/output sources.
|
|
||||||
int yylex( FLEX_STD istream& new_in, FLEX_STD ostream& new_out )
|
|
||||||
{
|
|
||||||
switch_streams( new_in, new_out );
|
|
||||||
return yylex();
|
|
||||||
}
|
|
||||||
|
|
||||||
int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0)
|
|
||||||
{
|
|
||||||
switch_streams( new_in, new_out );
|
|
||||||
return yylex();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch to new input/output streams. A nil stream pointer
|
|
||||||
// indicates "keep the current one".
|
|
||||||
virtual void switch_streams( FLEX_STD istream* new_in,
|
|
||||||
FLEX_STD ostream* new_out ) = 0;
|
|
||||||
virtual void switch_streams( FLEX_STD istream& new_in,
|
|
||||||
FLEX_STD ostream& new_out ) = 0;
|
|
||||||
|
|
||||||
int lineno() const { return yylineno; }
|
|
||||||
|
|
||||||
int debug() const { return yy_flex_debug; }
|
|
||||||
void set_debug( int flag ) { yy_flex_debug = flag; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
char* yytext;
|
|
||||||
int yyleng;
|
|
||||||
int yylineno; // only maintained if you use %option yylineno
|
|
||||||
int yy_flex_debug; // only has effect with -d or "%option debug"
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif // FLEXLEXER_H
|
|
||||||
|
|
||||||
#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
|
|
||||||
// Either this is the first time through (yyFlexLexerOnce not defined),
|
|
||||||
// or this is a repeated include to define a different flavor of
|
|
||||||
// yyFlexLexer, as discussed in the flex manual.
|
|
||||||
#define yyFlexLexerOnce
|
|
||||||
|
|
||||||
extern "C++" {
|
|
||||||
|
|
||||||
class yyFlexLexer : public FlexLexer {
|
|
||||||
public:
|
|
||||||
// arg_yyin and arg_yyout default to the cin and cout, but we
|
|
||||||
// only make that assignment when initializing in yylex().
|
|
||||||
yyFlexLexer( FLEX_STD istream& arg_yyin, FLEX_STD ostream& arg_yyout );
|
|
||||||
yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 );
|
|
||||||
private:
|
|
||||||
void ctor_common();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
virtual ~yyFlexLexer();
|
|
||||||
|
|
||||||
void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
|
|
||||||
struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size );
|
|
||||||
struct yy_buffer_state* yy_create_buffer( FLEX_STD istream& s, int size );
|
|
||||||
void yy_delete_buffer( struct yy_buffer_state* b );
|
|
||||||
void yyrestart( FLEX_STD istream* s );
|
|
||||||
void yyrestart( FLEX_STD istream& s );
|
|
||||||
|
|
||||||
void yypush_buffer_state( struct yy_buffer_state* new_buffer );
|
|
||||||
void yypop_buffer_state();
|
|
||||||
|
|
||||||
virtual int yylex();
|
|
||||||
virtual void switch_streams( FLEX_STD istream& new_in, FLEX_STD ostream& new_out );
|
|
||||||
virtual void switch_streams( FLEX_STD istream* new_in = 0, FLEX_STD ostream* new_out = 0 );
|
|
||||||
virtual int yywrap();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual int LexerInput( char* buf, int max_size );
|
|
||||||
virtual void LexerOutput( const char* buf, int size );
|
|
||||||
virtual void LexerError( const char* msg );
|
|
||||||
|
|
||||||
void yyunput( int c, char* buf_ptr );
|
|
||||||
int yyinput();
|
|
||||||
|
|
||||||
void yy_load_buffer_state();
|
|
||||||
void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream& s );
|
|
||||||
void yy_flush_buffer( struct yy_buffer_state* b );
|
|
||||||
|
|
||||||
int yy_start_stack_ptr;
|
|
||||||
int yy_start_stack_depth;
|
|
||||||
int* yy_start_stack;
|
|
||||||
|
|
||||||
void yy_push_state( int new_state );
|
|
||||||
void yy_pop_state();
|
|
||||||
int yy_top_state();
|
|
||||||
|
|
||||||
yy_state_type yy_get_previous_state();
|
|
||||||
yy_state_type yy_try_NUL_trans( yy_state_type current_state );
|
|
||||||
int yy_get_next_buffer();
|
|
||||||
|
|
||||||
FLEX_STD istream yyin; // input source for default LexerInput
|
|
||||||
FLEX_STD ostream yyout; // output sink for default LexerOutput
|
|
||||||
|
|
||||||
// yy_hold_char holds the character lost when yytext is formed.
|
|
||||||
char yy_hold_char;
|
|
||||||
|
|
||||||
// Number of characters read into yy_ch_buf.
|
|
||||||
int yy_n_chars;
|
|
||||||
|
|
||||||
// Points to current character in buffer.
|
|
||||||
char* yy_c_buf_p;
|
|
||||||
|
|
||||||
int yy_init; // whether we need to initialize
|
|
||||||
int yy_start; // start state number
|
|
||||||
|
|
||||||
// Flag which is used to allow yywrap()'s to do buffer switches
|
|
||||||
// instead of setting up a fresh yyin. A bit of a hack ...
|
|
||||||
int yy_did_buffer_switch_on_eof;
|
|
||||||
|
|
||||||
|
|
||||||
size_t yy_buffer_stack_top; /**< index of top of stack. */
|
|
||||||
size_t yy_buffer_stack_max; /**< capacity of stack. */
|
|
||||||
struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */
|
|
||||||
void yyensure_buffer_stack(void);
|
|
||||||
|
|
||||||
// The following are not always needed, but may be depending
|
|
||||||
// on use of certain flex features (like REJECT or yymore()).
|
|
||||||
|
|
||||||
yy_state_type yy_last_accepting_state;
|
|
||||||
char* yy_last_accepting_cpos;
|
|
||||||
|
|
||||||
yy_state_type* yy_state_buf;
|
|
||||||
yy_state_type* yy_state_ptr;
|
|
||||||
|
|
||||||
char* yy_full_match;
|
|
||||||
int* yy_full_state;
|
|
||||||
int yy_full_lp;
|
|
||||||
|
|
||||||
int yy_lp;
|
|
||||||
int yy_looking_for_trail_begin;
|
|
||||||
|
|
||||||
int yy_more_flag;
|
|
||||||
int yy_more_len;
|
|
||||||
int yy_more_offset;
|
|
||||||
int yy_prev_more_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // yyFlexLexer || ! yyFlexLexerOnce
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
|||||||
#ifndef _SYSYF_DRIVER_H_
|
|
||||||
#define _SYSYF_DRIVER_H_
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
// Generated by bison:
|
|
||||||
#include "SysYFParser.h"
|
|
||||||
|
|
||||||
#include "SysYFFlexLexer.h"
|
|
||||||
|
|
||||||
// Conducting the whole scanning and parsing of SysYF.
|
|
||||||
class SysYFDriver
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SysYFDriver();
|
|
||||||
virtual ~SysYFDriver();
|
|
||||||
|
|
||||||
std::map<std::string, int> variables;
|
|
||||||
|
|
||||||
int result;
|
|
||||||
|
|
||||||
// SysYF lexer
|
|
||||||
SysYFFlexLexer lexer;
|
|
||||||
|
|
||||||
std::ifstream instream;
|
|
||||||
|
|
||||||
// Handling the SysYF scanner.
|
|
||||||
void scan_begin();
|
|
||||||
void scan_end();
|
|
||||||
bool trace_scanning;
|
|
||||||
|
|
||||||
// Run the parser on file F.
|
|
||||||
// Return 0 on success.
|
|
||||||
SysYF::Ptr<SysYF::SyntaxTree::Node> parse(const std::string& f);
|
|
||||||
// The name of the file being parsed.
|
|
||||||
// Used later to pass the file name to the location tracker.
|
|
||||||
std::string file;
|
|
||||||
// Whether parser traces should be generated.
|
|
||||||
bool trace_parsing;
|
|
||||||
|
|
||||||
// Error handling.
|
|
||||||
void error(const yy::location& l, const std::string& m);
|
|
||||||
void error(const std::string& m);
|
|
||||||
|
|
||||||
SysYF::Ptr<SysYF::SyntaxTree::Node> root = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _SYSYF_DRIVER_H_
|
|
@ -1,37 +0,0 @@
|
|||||||
#ifndef _SYSYF_FLEX_LEXER_H_
|
|
||||||
#define _SYSYF_FLEX_LEXER_H_
|
|
||||||
|
|
||||||
#ifndef YY_DECL
|
|
||||||
#define YY_DECL \
|
|
||||||
yy::SysYFParser::symbol_type SysYFFlexLexer::yylex(SysYFDriver& driver)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// We need this for yyFlexLexer. If we don't #undef yyFlexLexer, the
|
|
||||||
// preprocessor chokes on the line `#define yyFlexLexer yyFlexLexer`
|
|
||||||
// in `FlexLexer.h`:
|
|
||||||
#undef yyFlexLexer
|
|
||||||
#include <FlexLexer.h>
|
|
||||||
|
|
||||||
// We need this for the yy::SysYFParser::symbol_type:
|
|
||||||
#include "SysYFParser.h"
|
|
||||||
|
|
||||||
// We need this for the yy::location type:
|
|
||||||
#include "location.hh"
|
|
||||||
|
|
||||||
class SysYFFlexLexer : public yyFlexLexer {
|
|
||||||
public:
|
|
||||||
// Use the superclass's constructor:
|
|
||||||
using yyFlexLexer::yyFlexLexer;
|
|
||||||
|
|
||||||
// Provide the interface to `yylex`; `flex` will emit the
|
|
||||||
// definition into `SysYFScanner.cpp`:
|
|
||||||
yy::SysYFParser::symbol_type yylex(SysYFDriver& driver);
|
|
||||||
|
|
||||||
// This seems like a reasonable place to put the location object
|
|
||||||
// rather than it being static (in the sense of having internal
|
|
||||||
// linkage at translation unit scope, not in the sense of being a
|
|
||||||
// class variable):
|
|
||||||
yy::location loc;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _SYSYF_FLEX_LEXER_H_
|
|
File diff suppressed because it is too large
Load Diff
@ -1,304 +0,0 @@
|
|||||||
// A Bison parser, made by GNU Bison 3.8.2.
|
|
||||||
|
|
||||||
// Locations for Bison parsers in C++
|
|
||||||
|
|
||||||
// Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// As a special exception, you may create a larger work that contains
|
|
||||||
// part or all of the Bison parser skeleton and distribute that work
|
|
||||||
// under terms of your choice, so long as that work isn't itself a
|
|
||||||
// parser generator using the skeleton or a modified version thereof
|
|
||||||
// as a parser skeleton. Alternatively, if you modify or redistribute
|
|
||||||
// the parser skeleton itself, you may (at your option) remove this
|
|
||||||
// special exception, which will cause the skeleton and the resulting
|
|
||||||
// Bison output files to be licensed under the GNU General Public
|
|
||||||
// License without this special exception.
|
|
||||||
|
|
||||||
// This special exception was added by the Free Software Foundation in
|
|
||||||
// version 2.2 of Bison.
|
|
||||||
|
|
||||||
/**
|
|
||||||
** \file ./location.hh
|
|
||||||
** Define the yy::location class.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef YY_YY_HOME_CJB_COMPILER_EDUCODER_EDUCODER_2021FALL_COMPILER_IR_LAB_SYSYF_TA_BUILD_LOCATION_HH_INCLUDED
|
|
||||||
# define YY_YY_HOME_CJB_COMPILER_EDUCODER_EDUCODER_2021FALL_COMPILER_IR_LAB_SYSYF_TA_BUILD_LOCATION_HH_INCLUDED
|
|
||||||
|
|
||||||
# include <iostream>
|
|
||||||
# include <string>
|
|
||||||
|
|
||||||
# ifndef YY_NULLPTR
|
|
||||||
# if defined __cplusplus
|
|
||||||
# if 201103L <= __cplusplus
|
|
||||||
# define YY_NULLPTR nullptr
|
|
||||||
# else
|
|
||||||
# define YY_NULLPTR 0
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define YY_NULLPTR ((void*)0)
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
namespace yy {
|
|
||||||
#line 58 "./location.hh"
|
|
||||||
|
|
||||||
/// A point in a source file.
|
|
||||||
class position
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/// Type for file name.
|
|
||||||
typedef const std::string filename_type;
|
|
||||||
/// Type for line and column numbers.
|
|
||||||
typedef int counter_type;
|
|
||||||
|
|
||||||
/// Construct a position.
|
|
||||||
explicit position (filename_type* f = YY_NULLPTR,
|
|
||||||
counter_type l = 1,
|
|
||||||
counter_type c = 1)
|
|
||||||
: filename (f)
|
|
||||||
, line (l)
|
|
||||||
, column (c)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
/// Initialization.
|
|
||||||
void initialize (filename_type* fn = YY_NULLPTR,
|
|
||||||
counter_type l = 1,
|
|
||||||
counter_type c = 1)
|
|
||||||
{
|
|
||||||
filename = fn;
|
|
||||||
line = l;
|
|
||||||
column = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \name Line and Column related manipulators
|
|
||||||
** \{ */
|
|
||||||
/// (line related) Advance to the COUNT next lines.
|
|
||||||
void lines (counter_type count = 1)
|
|
||||||
{
|
|
||||||
if (count)
|
|
||||||
{
|
|
||||||
column = 1;
|
|
||||||
line = add_ (line, count, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// (column related) Advance to the COUNT next columns.
|
|
||||||
void columns (counter_type count = 1)
|
|
||||||
{
|
|
||||||
column = add_ (column, count, 1);
|
|
||||||
}
|
|
||||||
/** \} */
|
|
||||||
|
|
||||||
/// File name to which this position refers.
|
|
||||||
filename_type* filename;
|
|
||||||
/// Current line number.
|
|
||||||
counter_type line;
|
|
||||||
/// Current column number.
|
|
||||||
counter_type column;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Compute max (min, lhs+rhs).
|
|
||||||
static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min)
|
|
||||||
{
|
|
||||||
return lhs + rhs < min ? min : lhs + rhs;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Add \a width columns, in place.
|
|
||||||
inline position&
|
|
||||||
operator+= (position& res, position::counter_type width)
|
|
||||||
{
|
|
||||||
res.columns (width);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add \a width columns.
|
|
||||||
inline position
|
|
||||||
operator+ (position res, position::counter_type width)
|
|
||||||
{
|
|
||||||
return res += width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subtract \a width columns, in place.
|
|
||||||
inline position&
|
|
||||||
operator-= (position& res, position::counter_type width)
|
|
||||||
{
|
|
||||||
return res += -width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subtract \a width columns.
|
|
||||||
inline position
|
|
||||||
operator- (position res, position::counter_type width)
|
|
||||||
{
|
|
||||||
return res -= width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Intercept output stream redirection.
|
|
||||||
** \param ostr the destination output stream
|
|
||||||
** \param pos a reference to the position to redirect
|
|
||||||
*/
|
|
||||||
template <typename YYChar>
|
|
||||||
std::basic_ostream<YYChar>&
|
|
||||||
operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
|
|
||||||
{
|
|
||||||
if (pos.filename)
|
|
||||||
ostr << *pos.filename << ':';
|
|
||||||
return ostr << pos.line << '.' << pos.column;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Two points in a source file.
|
|
||||||
class location
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/// Type for file name.
|
|
||||||
typedef position::filename_type filename_type;
|
|
||||||
/// Type for line and column numbers.
|
|
||||||
typedef position::counter_type counter_type;
|
|
||||||
|
|
||||||
/// Construct a location from \a b to \a e.
|
|
||||||
location (const position& b, const position& e)
|
|
||||||
: begin (b)
|
|
||||||
, end (e)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/// Construct a 0-width location in \a p.
|
|
||||||
explicit location (const position& p = position ())
|
|
||||||
: begin (p)
|
|
||||||
, end (p)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/// Construct a 0-width location in \a f, \a l, \a c.
|
|
||||||
explicit location (filename_type* f,
|
|
||||||
counter_type l = 1,
|
|
||||||
counter_type c = 1)
|
|
||||||
: begin (f, l, c)
|
|
||||||
, end (f, l, c)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
/// Initialization.
|
|
||||||
void initialize (filename_type* f = YY_NULLPTR,
|
|
||||||
counter_type l = 1,
|
|
||||||
counter_type c = 1)
|
|
||||||
{
|
|
||||||
begin.initialize (f, l, c);
|
|
||||||
end = begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \name Line and Column related manipulators
|
|
||||||
** \{ */
|
|
||||||
public:
|
|
||||||
/// Reset initial location to final location.
|
|
||||||
void step ()
|
|
||||||
{
|
|
||||||
begin = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extend the current location to the COUNT next columns.
|
|
||||||
void columns (counter_type count = 1)
|
|
||||||
{
|
|
||||||
end += count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extend the current location to the COUNT next lines.
|
|
||||||
void lines (counter_type count = 1)
|
|
||||||
{
|
|
||||||
end.lines (count);
|
|
||||||
}
|
|
||||||
/** \} */
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Beginning of the located region.
|
|
||||||
position begin;
|
|
||||||
/// End of the located region.
|
|
||||||
position end;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Join two locations, in place.
|
|
||||||
inline location&
|
|
||||||
operator+= (location& res, const location& end)
|
|
||||||
{
|
|
||||||
res.end = end.end;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Join two locations.
|
|
||||||
inline location
|
|
||||||
operator+ (location res, const location& end)
|
|
||||||
{
|
|
||||||
return res += end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add \a width columns to the end position, in place.
|
|
||||||
inline location&
|
|
||||||
operator+= (location& res, location::counter_type width)
|
|
||||||
{
|
|
||||||
res.columns (width);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add \a width columns to the end position.
|
|
||||||
inline location
|
|
||||||
operator+ (location res, location::counter_type width)
|
|
||||||
{
|
|
||||||
return res += width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subtract \a width columns to the end position, in place.
|
|
||||||
inline location&
|
|
||||||
operator-= (location& res, location::counter_type width)
|
|
||||||
{
|
|
||||||
return res += -width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subtract \a width columns to the end position.
|
|
||||||
inline location
|
|
||||||
operator- (location res, location::counter_type width)
|
|
||||||
{
|
|
||||||
return res -= width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Intercept output stream redirection.
|
|
||||||
** \param ostr the destination output stream
|
|
||||||
** \param loc a reference to the location to redirect
|
|
||||||
**
|
|
||||||
** Avoid duplicate information.
|
|
||||||
*/
|
|
||||||
template <typename YYChar>
|
|
||||||
std::basic_ostream<YYChar>&
|
|
||||||
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
|
|
||||||
{
|
|
||||||
location::counter_type end_col
|
|
||||||
= 0 < loc.end.column ? loc.end.column - 1 : 0;
|
|
||||||
ostr << loc.begin;
|
|
||||||
if (loc.end.filename
|
|
||||||
&& (!loc.begin.filename
|
|
||||||
|| *loc.begin.filename != *loc.end.filename))
|
|
||||||
ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
|
|
||||||
else if (loc.begin.line < loc.end.line)
|
|
||||||
ostr << '-' << loc.end.line << '.' << end_col;
|
|
||||||
else if (loc.begin.column < end_col)
|
|
||||||
ostr << '-' << end_col;
|
|
||||||
return ostr;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // yy
|
|
||||||
#line 303 "./location.hh"
|
|
||||||
|
|
||||||
#endif // !YY_YY_HOME_CJB_COMPILER_EDUCODER_EDUCODER_2021FALL_COMPILER_IR_LAB_SYSYF_TA_BUILD_LOCATION_HH_INCLUDED
|
|
@ -1,11 +0,0 @@
|
|||||||
// A Bison parser, made by GNU Bison 3.8.2.
|
|
||||||
|
|
||||||
// Starting with Bison 3.2, this file is useless: the structure it
|
|
||||||
// used to define is now defined in "location.hh".
|
|
||||||
//
|
|
||||||
// To get rid of this file:
|
|
||||||
// 1. add '%require "3.2"' (or newer) to your grammar file
|
|
||||||
// 2. remove references to this file from your build system
|
|
||||||
// 3. if you used to include it, include "location.hh" instead.
|
|
||||||
|
|
||||||
#include "location.hh"
|
|
@ -1,8 +0,0 @@
|
|||||||
// A Bison parser, made by GNU Bison 3.8.2.
|
|
||||||
|
|
||||||
// Starting with Bison 3.2, this file is useless: the structure it
|
|
||||||
// used to define is now defined with the parser itself.
|
|
||||||
//
|
|
||||||
// To get rid of this file:
|
|
||||||
// 1. add '%require "3.2"' (or newer) to your grammar file
|
|
||||||
// 2. remove references to this file from your build system.
|
|
@ -1,86 +0,0 @@
|
|||||||
#ifndef _SYSYF_BASICBLOCK_H_
|
|
||||||
#define _SYSYF_BASICBLOCK_H_
|
|
||||||
|
|
||||||
#include "Value.h"
|
|
||||||
#include "Instruction.h"
|
|
||||||
#include "Module.h"
|
|
||||||
#include "Function.h"
|
|
||||||
|
|
||||||
#include <list>
|
|
||||||
#include <set>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
class Function;
|
|
||||||
class Instruction;
|
|
||||||
class Module;
|
|
||||||
|
|
||||||
class BasicBlock : public Value
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static Ptr<BasicBlock> create(Ptr<Module> m, const std::string &name ,
|
|
||||||
Ptr<Function> parent ) {
|
|
||||||
auto prefix = name.empty() ? "" : "label_";
|
|
||||||
RET_AFTER_INIT(BasicBlock, m, prefix + name, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return parent, or null if none.
|
|
||||||
Ptr<Function> get_parent() { return parent_; }
|
|
||||||
|
|
||||||
Ptr<Module> get_module();
|
|
||||||
|
|
||||||
/****************api about cfg****************/
|
|
||||||
|
|
||||||
PtrList<BasicBlock> &get_pre_basic_blocks() { return pre_bbs_; }
|
|
||||||
PtrList<BasicBlock> &get_succ_basic_blocks() { return succ_bbs_; }
|
|
||||||
void add_pre_basic_block(Ptr<BasicBlock> bb) { pre_bbs_.push_back(bb); }
|
|
||||||
void add_succ_basic_block(Ptr<BasicBlock> bb) { succ_bbs_.push_back(bb); }
|
|
||||||
|
|
||||||
void remove_pre_basic_block(Ptr<BasicBlock> bb) { pre_bbs_.remove(bb); }
|
|
||||||
void remove_succ_basic_block(Ptr<BasicBlock> bb) { succ_bbs_.remove(bb); }
|
|
||||||
|
|
||||||
/****************api about cfg****************/
|
|
||||||
|
|
||||||
/// Returns the terminator instruction if the block is well formed or null
|
|
||||||
/// if the block is not well formed.
|
|
||||||
const Ptr<Instruction> get_terminator() const;
|
|
||||||
Ptr<Instruction> get_terminator() {
|
|
||||||
return const_pointer_cast<Instruction>(
|
|
||||||
static_pointer_cast<const BasicBlock>(shared_from_this())->get_terminator());
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_instruction(Ptr<Instruction> instr);
|
|
||||||
void add_instruction(PtrList<Instruction>::iterator instr_pos, Ptr<Instruction> instr);
|
|
||||||
void add_instr_begin(Ptr<Instruction> instr);
|
|
||||||
|
|
||||||
PtrList<Instruction>::iterator find_instruction(Ptr<Instruction> instr);
|
|
||||||
|
|
||||||
void delete_instr(Ptr<Instruction> instr);
|
|
||||||
|
|
||||||
bool empty() { return instr_list_.empty(); }
|
|
||||||
|
|
||||||
int get_num_of_instr() { return instr_list_.size(); }
|
|
||||||
PtrList<Instruction> &get_instructions() { return instr_list_; }
|
|
||||||
|
|
||||||
void erase_from_parent();
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit BasicBlock(Ptr<Module> m, const std::string &name ,
|
|
||||||
Ptr<Function> parent );
|
|
||||||
void init(Ptr<Module> m, const std::string &name ,
|
|
||||||
Ptr<Function> parent );
|
|
||||||
PtrList<BasicBlock> pre_bbs_;
|
|
||||||
PtrList<BasicBlock> succ_bbs_;
|
|
||||||
PtrList<Instruction> instr_list_;
|
|
||||||
Ptr<Function> parent_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _SYSYF_BASICBLOCK_H_
|
|
@ -1,90 +0,0 @@
|
|||||||
#ifndef _SYSYF_CONSTANT_H_
|
|
||||||
#define _SYSYF_CONSTANT_H_
|
|
||||||
#include "User.h"
|
|
||||||
#include "Value.h"
|
|
||||||
#include "Type.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
class Constant : public User
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
explicit Constant(Ptr<Type> ty, const std::string &name = "", unsigned num_ops = 0)
|
|
||||||
: User(ty, name, num_ops) {}
|
|
||||||
void init(Ptr<Type> ty, const std::string &name = "", unsigned num_ops = 0) {}
|
|
||||||
// int value;
|
|
||||||
public:
|
|
||||||
~Constant() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConstantInt : public Constant
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
int value_;
|
|
||||||
explicit ConstantInt(Ptr<Type> ty, int val)
|
|
||||||
: Constant(ty,"",0),value_(val) {}
|
|
||||||
void init(Ptr<Type> ty, int val);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
static int get_value(Ptr<ConstantInt> const_val) { return const_val->value_; }
|
|
||||||
int get_value() { return value_; }
|
|
||||||
static Ptr<ConstantInt> create(int val, Ptr<Module> m);
|
|
||||||
static Ptr<ConstantInt> create(bool val, Ptr<Module> m);
|
|
||||||
virtual std::string print() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConstantFloat : public Constant
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
float value_;
|
|
||||||
explicit ConstantFloat(Ptr<Type> ty,float val)
|
|
||||||
: Constant(ty,"",0),value_(val) {}
|
|
||||||
void init(Ptr<Type> ty, float val);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
static float get_value(Ptr<ConstantFloat> const_val) { return const_val->value_; }
|
|
||||||
float get_value() { return value_; }
|
|
||||||
static Ptr<ConstantFloat> create(float val, Ptr<Module> m);
|
|
||||||
virtual std::string print() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConstantArray : public Constant
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
PtrVec<Constant> const_array;
|
|
||||||
explicit ConstantArray(Ptr<ArrayType> ty, const PtrVec<Constant> &val);
|
|
||||||
void init(Ptr<ArrayType> ty, const PtrVec<Constant> &val);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
~ConstantArray() = default;
|
|
||||||
|
|
||||||
Ptr<Constant> get_element_value(int index);
|
|
||||||
|
|
||||||
unsigned get_size_of_array() { return const_array.size(); }
|
|
||||||
|
|
||||||
static Ptr<ConstantArray> create(Ptr<ArrayType> ty, const PtrVec<Constant> &val);
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConstantZero : public Constant
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit ConstantZero(Ptr<Type> ty)
|
|
||||||
: Constant(ty,"",0) {}
|
|
||||||
void init(Ptr<Type> ty);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<ConstantZero> create(Ptr<Type> ty, Ptr<Module> m);
|
|
||||||
virtual std::string print() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //_SYSYF_CONSTANT_H_
|
|
@ -1,110 +0,0 @@
|
|||||||
#ifndef _SYSYF_FUNCTION_H_
|
|
||||||
#define _SYSYF_FUNCTION_H_
|
|
||||||
|
|
||||||
#include <iterator>
|
|
||||||
#include <list>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <map>
|
|
||||||
#ifdef DEBUG
|
|
||||||
#include <cassert>
|
|
||||||
#endif
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#include "User.h"
|
|
||||||
#include "Module.h"
|
|
||||||
#include "BasicBlock.h"
|
|
||||||
#include "Type.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
class Module;
|
|
||||||
class Argument;
|
|
||||||
class BasicBlock;
|
|
||||||
class Type;
|
|
||||||
class FunctionType;
|
|
||||||
|
|
||||||
class Function : public Value
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~Function() = default;
|
|
||||||
static Ptr<Function> create(Ptr<FunctionType> ty, const std::string &name, Ptr<Module> parent);
|
|
||||||
|
|
||||||
Ptr<FunctionType> get_function_type() const;
|
|
||||||
|
|
||||||
Ptr<Type> get_return_type() const;
|
|
||||||
|
|
||||||
void add_basic_block(Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
unsigned get_num_of_args() const;
|
|
||||||
unsigned get_num_basic_blocks() const;
|
|
||||||
|
|
||||||
Ptr<Module> get_parent() const;
|
|
||||||
|
|
||||||
PtrList<Argument>::iterator arg_begin() { return arguments_.begin(); }
|
|
||||||
PtrList<Argument>::iterator arg_end() { return arguments_.end(); }
|
|
||||||
|
|
||||||
void remove(Ptr<BasicBlock> bb);
|
|
||||||
Ptr<BasicBlock> get_entry_block() { return *basic_blocks_.begin(); }
|
|
||||||
|
|
||||||
PtrList<BasicBlock> &get_basic_blocks() { return basic_blocks_; }
|
|
||||||
PtrList<Argument> &get_args() { return arguments_; }
|
|
||||||
std::vector<PtrSet<Value>> &get_vreg_set(){ return vreg_set_;}
|
|
||||||
|
|
||||||
bool is_declaration() { return basic_blocks_.empty(); }
|
|
||||||
void set_unused_reg_num(std::set<int>& set){unused_reg_num_ = set;}
|
|
||||||
std::set<int>& get_unused_reg_num(){return unused_reg_num_;}
|
|
||||||
|
|
||||||
void set_instr_name();
|
|
||||||
std::string print();
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit Function(Ptr<FunctionType> ty, const std::string &name, Ptr<Module> parent);
|
|
||||||
void init(Ptr<FunctionType> ty, const std::string &name, Ptr<Module> parent);
|
|
||||||
void build_args();
|
|
||||||
|
|
||||||
private:
|
|
||||||
PtrList<BasicBlock> basic_blocks_; // basic blocks
|
|
||||||
PtrList<Argument> arguments_; // arguments
|
|
||||||
std::vector<PtrSet<Value>> vreg_set_;
|
|
||||||
Ptr<Module> parent_;
|
|
||||||
std::set<int> unused_reg_num_;
|
|
||||||
unsigned seq_cnt_;
|
|
||||||
// unsigned num_args_;
|
|
||||||
// We don't need this, all value inside function should be unnamed
|
|
||||||
// std::map<std::string, Ptr<Value>> sym_table_; // Symbol table of args/instructions
|
|
||||||
};
|
|
||||||
|
|
||||||
// Argument of Function, does not contain actual value
|
|
||||||
class Argument : public Value
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static Ptr<Argument> create(Ptr<Type> ty, const std::string &name = "", Ptr<Function> f = nullptr,
|
|
||||||
unsigned arg_no = 0);
|
|
||||||
~Argument() = default;
|
|
||||||
|
|
||||||
inline const Ptr<Function> get_parent() const { return parent_; }
|
|
||||||
inline Ptr<Function> get_parent() { return parent_; }
|
|
||||||
|
|
||||||
/// For example in "void foo(int a, float b)" a is 0 and b is 1.
|
|
||||||
unsigned get_arg_no() const {
|
|
||||||
#ifdef DEBUG
|
|
||||||
assert(parent_ && "can't get number of unparented arg");
|
|
||||||
#endif
|
|
||||||
return arg_no_;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string print() override ;
|
|
||||||
private:
|
|
||||||
// Argument constructor.
|
|
||||||
explicit Argument(Ptr<Type> ty, const std::string &name = "", Ptr<Function> f = nullptr,
|
|
||||||
unsigned arg_no = 0)
|
|
||||||
: Value(ty, name), parent_(f), arg_no_(arg_no) {}
|
|
||||||
Ptr<Function> parent_;
|
|
||||||
unsigned arg_no_; // argument No.
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // _SYSYF_FUNCTION_H_
|
|
@ -1,31 +0,0 @@
|
|||||||
#ifndef _SYSYF_GLOBALVARIABLE_H_
|
|
||||||
#define _SYSYF_GLOBALVARIABLE_H_
|
|
||||||
|
|
||||||
#include "Module.h"
|
|
||||||
#include "User.h"
|
|
||||||
#include "Constant.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
class GlobalVariable : public User
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
bool is_const_ ;
|
|
||||||
Ptr<Constant> init_val_;
|
|
||||||
explicit GlobalVariable(std::string name, Ptr<Module> m, Ptr<Type> ty, bool is_const, Ptr<Constant> init_val = nullptr);
|
|
||||||
void init(std::string name, Ptr<Module> m, Ptr<Type> ty, bool is_const, Ptr<Constant> init_val = nullptr);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<GlobalVariable> create(std::string name, Ptr<Module> m, Ptr<Type> ty, bool is_const, Ptr<Constant> init_val);
|
|
||||||
|
|
||||||
Ptr<Constant> get_init() { return init_val_; }
|
|
||||||
bool is_const() { return is_const_; }
|
|
||||||
std::string print();
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //_SYSYF_GLOBALVARIABLE_H_
|
|
@ -1,25 +0,0 @@
|
|||||||
#ifndef _SYSYF_IPRINTER_H_
|
|
||||||
#define _SYSYF_IPRINTER_H_
|
|
||||||
|
|
||||||
#include "Value.h"
|
|
||||||
#include "Module.h"
|
|
||||||
#include "Function.h"
|
|
||||||
#include "GlobalVariable.h"
|
|
||||||
#include "Constant.h"
|
|
||||||
#include "BasicBlock.h"
|
|
||||||
#include "Instruction.h"
|
|
||||||
#include "User.h"
|
|
||||||
#include "Type.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
std::string print_as_op(Ptr<Value> v, bool print_ty );
|
|
||||||
std::string print_cmp_type(CmpInst::CmpOp op);
|
|
||||||
std::string print_fcmp_type(FCmpInst::CmpOp op);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,84 +0,0 @@
|
|||||||
#ifndef _SYSYF_IRSTMTBUILDER_H_
|
|
||||||
#define _SYSYF_IRSTMTBUILDER_H_
|
|
||||||
|
|
||||||
#include "BasicBlock.h"
|
|
||||||
#include "Instruction.h"
|
|
||||||
#include "Value.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
class IRStmtBuilder {
|
|
||||||
private:
|
|
||||||
Ptr<BasicBlock> BB_;
|
|
||||||
Ptr<Module> m_;
|
|
||||||
explicit IRStmtBuilder(Ptr<BasicBlock> bb, Ptr<Module> m) : BB_(bb), m_(m) {};
|
|
||||||
void init(Ptr<BasicBlock> bb, Ptr<Module> m) {}
|
|
||||||
public:
|
|
||||||
static Ptr<IRStmtBuilder> create(Ptr<BasicBlock> bb, Ptr<Module> m) { RET_AFTER_INIT(IRStmtBuilder, bb, m); }
|
|
||||||
~IRStmtBuilder() = default;
|
|
||||||
Ptr<Module> get_module(){return m_;}
|
|
||||||
Ptr<BasicBlock> get_insert_block() { return this->BB_; }
|
|
||||||
void set_insert_point(Ptr<BasicBlock> bb) { this->BB_ = bb; } //在某个基本块中插入指令
|
|
||||||
Ptr<BinaryInst> create_iadd( Ptr<Value> lhs, Ptr<Value> rhs){ return BinaryInst::create_add( lhs, rhs, this->BB_, m_);} //创建加法指令(以及其他算术指令)
|
|
||||||
Ptr<BinaryInst> create_isub( Ptr<Value> lhs, Ptr<Value> rhs){ return BinaryInst::create_sub( lhs, rhs, this->BB_, m_);}
|
|
||||||
Ptr<BinaryInst> create_imul( Ptr<Value> lhs, Ptr<Value> rhs){ return BinaryInst::create_mul( lhs, rhs, this->BB_, m_);}
|
|
||||||
Ptr<BinaryInst> create_isdiv( Ptr<Value> lhs, Ptr<Value> rhs){ return BinaryInst::create_sdiv( lhs, rhs, this->BB_, m_);}
|
|
||||||
Ptr<BinaryInst> create_isrem( Ptr<Value> lhs, Ptr<Value> rhs){ return BinaryInst::create_srem( lhs, rhs, this->BB_, m_);}
|
|
||||||
|
|
||||||
Ptr<CmpInst> create_icmp_eq( Ptr<Value> lhs, Ptr<Value> rhs){ return CmpInst::create_cmp(CmpInst::EQ, lhs, rhs, this->BB_, m_); }
|
|
||||||
Ptr<CmpInst> create_icmp_ne( Ptr<Value> lhs, Ptr<Value> rhs){ return CmpInst::create_cmp(CmpInst::NE, lhs, rhs, this->BB_, m_); }
|
|
||||||
Ptr<CmpInst> create_icmp_gt( Ptr<Value> lhs, Ptr<Value> rhs){ return CmpInst::create_cmp(CmpInst::GT, lhs, rhs, this->BB_, m_); }
|
|
||||||
Ptr<CmpInst> create_icmp_ge( Ptr<Value> lhs, Ptr<Value> rhs){ return CmpInst::create_cmp(CmpInst::GE, lhs, rhs, this->BB_, m_); }
|
|
||||||
Ptr<CmpInst> create_icmp_lt( Ptr<Value> lhs, Ptr<Value> rhs){ return CmpInst::create_cmp(CmpInst::LT, lhs, rhs, this->BB_, m_); }
|
|
||||||
Ptr<CmpInst> create_icmp_le( Ptr<Value> lhs, Ptr<Value> rhs){ return CmpInst::create_cmp(CmpInst::LE, lhs, rhs, this->BB_, m_); }
|
|
||||||
|
|
||||||
Ptr<BinaryInst> create_fadd( Ptr<Value> lhs, Ptr<Value> rhs){ return BinaryInst::create_fadd( lhs, rhs, this->BB_, m_);}
|
|
||||||
Ptr<BinaryInst> create_fsub( Ptr<Value> lhs, Ptr<Value> rhs){ return BinaryInst::create_fsub( lhs, rhs, this->BB_, m_);}
|
|
||||||
Ptr<BinaryInst> create_fmul( Ptr<Value> lhs, Ptr<Value> rhs){ return BinaryInst::create_fmul( lhs, rhs, this->BB_, m_);}
|
|
||||||
Ptr<BinaryInst> create_fdiv( Ptr<Value> lhs, Ptr<Value> rhs){ return BinaryInst::create_fdiv( lhs, rhs, this->BB_, m_);}
|
|
||||||
|
|
||||||
Ptr<FCmpInst> create_fcmp_eq( Ptr<Value> lhs, Ptr<Value> rhs){ return FCmpInst::create_fcmp(FCmpInst::EQ, lhs, rhs, this->BB_, m_); }
|
|
||||||
Ptr<FCmpInst> create_fcmp_ne( Ptr<Value> lhs, Ptr<Value> rhs){ return FCmpInst::create_fcmp(FCmpInst::NE, lhs, rhs, this->BB_, m_); }
|
|
||||||
Ptr<FCmpInst> create_fcmp_gt( Ptr<Value> lhs, Ptr<Value> rhs){ return FCmpInst::create_fcmp(FCmpInst::GT, lhs, rhs, this->BB_, m_); }
|
|
||||||
Ptr<FCmpInst> create_fcmp_ge( Ptr<Value> lhs, Ptr<Value> rhs){ return FCmpInst::create_fcmp(FCmpInst::GE, lhs, rhs, this->BB_, m_); }
|
|
||||||
Ptr<FCmpInst> create_fcmp_lt( Ptr<Value> lhs, Ptr<Value> rhs){ return FCmpInst::create_fcmp(FCmpInst::LT, lhs, rhs, this->BB_, m_); }
|
|
||||||
Ptr<FCmpInst> create_fcmp_le( Ptr<Value> lhs, Ptr<Value> rhs){ return FCmpInst::create_fcmp(FCmpInst::LE, lhs, rhs, this->BB_, m_); }
|
|
||||||
|
|
||||||
Ptr<CallInst> create_call(Ptr<Value> func, PtrVec<Value> args)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
assert( dynamic_pointer_cast<Function>(func) && "func must be Ptr<Function> type");
|
|
||||||
#endif
|
|
||||||
return CallInst::create(static_pointer_cast<Function>(func) ,args, this->BB_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ptr<BranchInst> create_br(Ptr<BasicBlock> if_true){ return BranchInst::create_br(if_true, this->BB_); }
|
|
||||||
Ptr<BranchInst> create_cond_br(Ptr<Value> cond, Ptr<BasicBlock> if_true, Ptr<BasicBlock> if_false){ return BranchInst::create_cond_br(cond, if_true, if_false,this->BB_); }
|
|
||||||
|
|
||||||
Ptr<ReturnInst> create_ret(Ptr<Value> val) { return ReturnInst::create_ret(val,this->BB_); }
|
|
||||||
Ptr<ReturnInst> create_void_ret() { return ReturnInst::create_void_ret(this->BB_); }
|
|
||||||
|
|
||||||
Ptr<GetElementPtrInst> create_gep(Ptr<Value> ptr, PtrVec<Value> idxs) { return GetElementPtrInst::create_gep(ptr, idxs, this->BB_); }
|
|
||||||
|
|
||||||
Ptr<StoreInst> create_store(Ptr<Value> val, Ptr<Value> ptr) { return StoreInst::create_store(val, ptr, this->BB_ ); }
|
|
||||||
Ptr<LoadInst> create_load(Ptr<Type> ty, Ptr<Value> ptr) { return LoadInst::create_load(ty, ptr, this->BB_); }
|
|
||||||
Ptr<LoadInst> create_load(Ptr<Value> ptr)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
assert( ptr->get_type()->is_pointer_type() && "ptr must be pointer type" );
|
|
||||||
#endif
|
|
||||||
return LoadInst::create_load(ptr->get_type()->get_pointer_element_type(), ptr, this->BB_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ptr<AllocaInst> create_alloca(Ptr<Type> ty) { return AllocaInst::create_alloca(ty, this->BB_); }
|
|
||||||
Ptr<ZextInst> create_zext(Ptr<Value> val, Ptr<Type> ty) { return ZextInst::create_zext(val, ty, this->BB_); }
|
|
||||||
Ptr<FpToSiInst> create_fptosi(Ptr<Value> val, Ptr<Type> ty) { return FpToSiInst::create_fptosi(val, ty, this->BB_); }
|
|
||||||
Ptr<SiToFpInst> create_sitofp(Ptr<Value> val, Ptr<Type> ty) { return SiToFpInst::create_sitofp(val, ty, this->BB_); }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _SYSYF_IRSTMTBUILDER_H_
|
|
@ -1,435 +0,0 @@
|
|||||||
#ifndef _SYSYF_INSTRUCTION_H_
|
|
||||||
#define _SYSYF_INSTRUCTION_H_
|
|
||||||
|
|
||||||
#include "User.h"
|
|
||||||
#include "Type.h"
|
|
||||||
#include "Constant.h"
|
|
||||||
#include "BasicBlock.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
class BasicBlock;
|
|
||||||
class Function;
|
|
||||||
class Instruction;
|
|
||||||
|
|
||||||
class Instruction : public User
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum OpID
|
|
||||||
{
|
|
||||||
// Terminator Instructions
|
|
||||||
ret,
|
|
||||||
br,
|
|
||||||
// Standard binary operators
|
|
||||||
add,
|
|
||||||
sub,
|
|
||||||
mul,
|
|
||||||
sdiv,
|
|
||||||
srem,
|
|
||||||
// Float binaru opeartors
|
|
||||||
fadd,
|
|
||||||
fsub,
|
|
||||||
fmul,
|
|
||||||
fdiv,
|
|
||||||
// Memory operators
|
|
||||||
alloca,
|
|
||||||
load,
|
|
||||||
store,
|
|
||||||
// Other operators
|
|
||||||
cmp,
|
|
||||||
fcmp,
|
|
||||||
phi,
|
|
||||||
call,
|
|
||||||
getelementptr,
|
|
||||||
// Zero extend
|
|
||||||
zext,
|
|
||||||
// type cast bewteen float and singed integer
|
|
||||||
fptosi,
|
|
||||||
sitofp,
|
|
||||||
};
|
|
||||||
inline const Ptr<BasicBlock> get_parent() const { return parent_; }
|
|
||||||
inline Ptr<BasicBlock> get_parent() { return parent_; }
|
|
||||||
void set_parent(Ptr<BasicBlock> parent) { this->parent_ = parent; }
|
|
||||||
// Return the function this instruction belongs to.
|
|
||||||
Ptr<Function> get_function();
|
|
||||||
Ptr<Module> get_module();
|
|
||||||
|
|
||||||
OpID get_instr_type() { return op_id_; }
|
|
||||||
std::string get_instr_op_name() {
|
|
||||||
switch (op_id_)
|
|
||||||
{
|
|
||||||
case ret: return "ret"; break;
|
|
||||||
case br: return "br"; break;
|
|
||||||
case add: return "add"; break;
|
|
||||||
case sub: return "sub"; break;
|
|
||||||
case mul: return "mul"; break;
|
|
||||||
case sdiv: return "sdiv"; break;
|
|
||||||
case srem: return "srem"; break;
|
|
||||||
case fadd: return "fadd"; break;
|
|
||||||
case fsub: return "fsub"; break;
|
|
||||||
case fmul: return "fmul"; break;
|
|
||||||
case fdiv: return "fdiv"; break;
|
|
||||||
case alloca: return "alloca"; break;
|
|
||||||
case load: return "load"; break;
|
|
||||||
case store: return "store"; break;
|
|
||||||
case cmp: return "cmp"; break;
|
|
||||||
case fcmp: return "fcmp"; break;
|
|
||||||
case phi: return "phi"; break;
|
|
||||||
case call: return "call"; break;
|
|
||||||
case getelementptr: return "getelementptr"; break;
|
|
||||||
case zext: return "zext"; break;
|
|
||||||
case fptosi: return "fptosi"; break;
|
|
||||||
case sitofp: return "sitofp"; break;
|
|
||||||
|
|
||||||
default: return ""; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool is_void() { return ((op_id_ == ret) || (op_id_ == br) || (op_id_ == store) || (op_id_ == call && this->get_type()->is_void_type())); }
|
|
||||||
|
|
||||||
bool is_phi() { return op_id_ == phi; }
|
|
||||||
bool is_store() { return op_id_ == store; }
|
|
||||||
bool is_alloca() { return op_id_ == alloca; }
|
|
||||||
bool is_ret() { return op_id_ == ret; }
|
|
||||||
bool is_load() { return op_id_ == load; }
|
|
||||||
bool is_br() { return op_id_ == br; }
|
|
||||||
|
|
||||||
bool is_add() { return op_id_ == add; }
|
|
||||||
bool is_sub() { return op_id_ == sub; }
|
|
||||||
bool is_mul() { return op_id_ == mul; }
|
|
||||||
bool is_div() { return op_id_ == sdiv; }
|
|
||||||
bool is_rem() { return op_id_ == srem; }
|
|
||||||
|
|
||||||
bool is_fadd() { return op_id_ == fadd; }
|
|
||||||
bool is_fsub() { return op_id_ == fsub; }
|
|
||||||
bool is_fmul() { return op_id_ == fmul; }
|
|
||||||
bool is_fdiv() { return op_id_ == fdiv; }
|
|
||||||
|
|
||||||
bool is_cmp() { return op_id_ == cmp; }
|
|
||||||
bool is_fcmp() { return op_id_ == fcmp; }
|
|
||||||
|
|
||||||
bool is_call() { return op_id_ == call; }
|
|
||||||
bool is_gep() { return op_id_ == getelementptr; }
|
|
||||||
bool is_zext() { return op_id_ == zext; }
|
|
||||||
bool is_fptosi() { return op_id_ == fptosi; }
|
|
||||||
bool is_sitofp() { return op_id_ == sitofp; }
|
|
||||||
|
|
||||||
bool isBinary()
|
|
||||||
{
|
|
||||||
return (is_add() || is_sub() || is_mul() || is_div() || is_rem() ||
|
|
||||||
is_fadd() || is_fsub() || is_fmul() || is_fdiv()) &&
|
|
||||||
(get_num_operand() == 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isTerminator() { return is_br() || is_ret(); }
|
|
||||||
|
|
||||||
void set_id(int id){id_ = id;}
|
|
||||||
int get_id() const{return id_;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
OpID op_id_;
|
|
||||||
int id_;
|
|
||||||
unsigned num_ops_;
|
|
||||||
Ptr<BasicBlock> parent_;
|
|
||||||
// must be called after Instruction() in any derived class
|
|
||||||
void insert_to_bb();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// create instruction, but not insert to bb (insert to bb in method create in the derived class)
|
|
||||||
// ty here is result type
|
|
||||||
explicit Instruction(Ptr<Type> ty, OpID id, unsigned num_ops, Ptr<BasicBlock> parent = nullptr);
|
|
||||||
void init(Ptr<Type> ty, OpID id, unsigned num_ops, Ptr<BasicBlock> parent = nullptr);
|
|
||||||
};
|
|
||||||
|
|
||||||
class BinaryInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit BinaryInst(Ptr<Type> ty, OpID id, Ptr<Value> v1, Ptr<Value> v2,
|
|
||||||
Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<BinaryInst> create_add(Ptr<Value> v1, Ptr<Value> v2, Ptr<BasicBlock> bb, Ptr<Module> m);
|
|
||||||
static Ptr<BinaryInst> create_sub(Ptr<Value> v1, Ptr<Value> v2, Ptr<BasicBlock> bb, Ptr<Module> m);
|
|
||||||
static Ptr<BinaryInst> create_mul(Ptr<Value> v1, Ptr<Value> v2, Ptr<BasicBlock> bb, Ptr<Module> m);
|
|
||||||
static Ptr<BinaryInst> create_sdiv(Ptr<Value> v1, Ptr<Value> v2, Ptr<BasicBlock> bb, Ptr<Module> m);
|
|
||||||
static Ptr<BinaryInst> create_srem(Ptr<Value> v1, Ptr<Value> v2, Ptr<BasicBlock> bb, Ptr<Module> m);
|
|
||||||
static Ptr<BinaryInst> create_fadd(Ptr<Value> v1, Ptr<Value> v2, Ptr<BasicBlock> bb, Ptr<Module> m);
|
|
||||||
static Ptr<BinaryInst> create_fsub(Ptr<Value> v1, Ptr<Value> v2, Ptr<BasicBlock> bb, Ptr<Module> m);
|
|
||||||
static Ptr<BinaryInst> create_fmul(Ptr<Value> v1, Ptr<Value> v2, Ptr<BasicBlock> bb, Ptr<Module> m);
|
|
||||||
static Ptr<BinaryInst> create_fdiv(Ptr<Value> v1, Ptr<Value> v2, Ptr<BasicBlock> bb, Ptr<Module> m);
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void init(Ptr<Type> ty, OpID id, Ptr<Value> v1, Ptr<Value> v2, Ptr<BasicBlock> bb);
|
|
||||||
void assertValid() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CmpInst : public Instruction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum CmpOp
|
|
||||||
{
|
|
||||||
EQ, // ==
|
|
||||||
NE, // !=
|
|
||||||
GT, // >
|
|
||||||
GE, // >=
|
|
||||||
LT, // <
|
|
||||||
LE // <=
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit CmpInst(Ptr<Type> ty, CmpOp op, Ptr<Value> lhs, Ptr<Value> rhs,
|
|
||||||
Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<CmpInst> create_cmp(CmpOp op, Ptr<Value> lhs, Ptr<Value> rhs,
|
|
||||||
Ptr<BasicBlock> bb, Ptr<Module> m);
|
|
||||||
|
|
||||||
CmpOp get_cmp_op() { return cmp_op_; }
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CmpOp cmp_op_;
|
|
||||||
void init(Ptr<Type> ty, CmpOp op, Ptr<Value> lhs, Ptr<Value> rhs, Ptr<BasicBlock> bb);
|
|
||||||
void assertValid() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class FCmpInst : public Instruction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum CmpOp
|
|
||||||
{
|
|
||||||
EQ, // ==
|
|
||||||
NE, // !=
|
|
||||||
GT, // >
|
|
||||||
GE, // >=
|
|
||||||
LT, // <
|
|
||||||
LE // <=
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit FCmpInst(Ptr<Type> ty, CmpOp op, Ptr<Value> lhs, Ptr<Value> rhs,
|
|
||||||
Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<Type> ty, CmpOp op, Ptr<Value> lhs, Ptr<Value> rhs, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<FCmpInst> create_fcmp(CmpOp op, Ptr<Value> lhs, Ptr<Value> rhs,
|
|
||||||
Ptr<BasicBlock> bb, Ptr<Module> m);
|
|
||||||
|
|
||||||
CmpOp get_cmp_op() { return cmp_op_; }
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CmpOp cmp_op_;
|
|
||||||
|
|
||||||
void assertValid() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CallInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit CallInst(Ptr<Function> func, PtrVec<Value> args, Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<Function> func, PtrVec<Value> args, Ptr<BasicBlock> bb);
|
|
||||||
explicit CallInst(Ptr<Type> ret_ty, PtrVec<Value> args, Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<Type> ret_ty, PtrVec<Value> args, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<CallInst> create(Ptr<Function> func, PtrVec<Value> args, Ptr<BasicBlock> bb);
|
|
||||||
Ptr<FunctionType> get_function_type() const;
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class BranchInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit BranchInst(Ptr<Value> cond, Ptr<BasicBlock> if_true, Ptr<BasicBlock> if_false,
|
|
||||||
Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<Value> cond, Ptr<BasicBlock> if_true, Ptr<BasicBlock> if_false,
|
|
||||||
Ptr<BasicBlock> bb);
|
|
||||||
explicit BranchInst(Ptr<Value> cond, Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<Value> cond, Ptr<BasicBlock> bb);
|
|
||||||
explicit BranchInst(Ptr<BasicBlock> if_true, Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<BasicBlock> if_true, Ptr<BasicBlock> bb);
|
|
||||||
explicit BranchInst(Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<BranchInst> create_cond_br(Ptr<Value> cond, Ptr<BasicBlock> if_true, Ptr<BasicBlock> if_false,
|
|
||||||
Ptr<BasicBlock> bb);
|
|
||||||
static Ptr<BranchInst> create_br(Ptr<BasicBlock> if_true, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
bool is_cond_br() const;
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class ReturnInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit ReturnInst(Ptr<Value> val, Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<Value> val, Ptr<BasicBlock> bb);
|
|
||||||
explicit ReturnInst(Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<ReturnInst> create_ret(Ptr<Value> val, Ptr<BasicBlock> bb);
|
|
||||||
static Ptr<ReturnInst> create_void_ret(Ptr<BasicBlock> bb);
|
|
||||||
bool is_void_ret() const;
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class GetElementPtrInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit GetElementPtrInst(Ptr<Value> ptr, PtrVec<Value> idxs, Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<Value> ptr, PtrVec<Value> idxs, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<Type> get_element_type(Ptr<Value> ptr, PtrVec<Value> idxs);
|
|
||||||
static Ptr<GetElementPtrInst> create_gep(Ptr<Value> ptr, PtrVec<Value> idxs, Ptr<BasicBlock> bb);
|
|
||||||
Ptr<Type> get_element_type() const;
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ptr<Type> element_ty_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class StoreInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit StoreInst(Ptr<Value> val, Ptr<Value> ptr, Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<Value> val, Ptr<Value> ptr, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<StoreInst> create_store(Ptr<Value> val, Ptr<Value> ptr, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
Ptr<Value> get_rval() { return this->get_operand(0); }
|
|
||||||
Ptr<Value> get_lval() { return this->get_operand(1); }
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class LoadInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit LoadInst(Ptr<Type> ty, Ptr<Value> ptr, Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<Type> ty, Ptr<Value> ptr, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<LoadInst> create_load(Ptr<Type> ty, Ptr<Value> ptr, Ptr<BasicBlock> bb);
|
|
||||||
Ptr<Value> get_lval() { return this->get_operand(0); }
|
|
||||||
|
|
||||||
Ptr<Type> get_load_type() const;
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class AllocaInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit AllocaInst(Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
void init(Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<AllocaInst> create_alloca(Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
Ptr<Type> get_alloca_type() const;
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ptr<Type> alloca_ty_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ZextInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit ZextInst(OpID op, Ptr<Value> val, Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
void init(OpID op, Ptr<Value> val, Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<ZextInst> create_zext(Ptr<Value> val, Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
Ptr<Type> get_dest_type() const;
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ptr<Type> dest_ty_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FpToSiInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit FpToSiInst(OpID op, Ptr<Value> val, Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
void init(OpID op, Ptr<Value> val, Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<FpToSiInst> create_fptosi(Ptr<Value> val, Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
Ptr<Type> get_dest_type() const;
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ptr<Type> dest_ty_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SiToFpInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit SiToFpInst(OpID op, Ptr<Value> val, Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
void init(OpID op, Ptr<Value> val, Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<SiToFpInst> create_sitofp(Ptr<Value> val, Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
Ptr<Type> get_dest_type() const;
|
|
||||||
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ptr<Type> dest_ty_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PhiInst : public Instruction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
explicit PhiInst(OpID op, PtrVec<Value> vals, PtrVec<BasicBlock> val_bbs, Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
void init(OpID op, PtrVec<Value> vals, PtrVec<BasicBlock> val_bbs, Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Ptr<PhiInst> create_phi(Ptr<Type> ty, Ptr<BasicBlock> bb);
|
|
||||||
Ptr<Value> get_lval() { return l_val_; }
|
|
||||||
void set_lval(Ptr<Value> l_val) { l_val_ = l_val; }
|
|
||||||
void add_phi_pair_operand(Ptr<Value> val, Ptr<Value> pre_bb)
|
|
||||||
{
|
|
||||||
this->add_operand(val);
|
|
||||||
this->add_operand(pre_bb);
|
|
||||||
}
|
|
||||||
virtual std::string print() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ptr<Value> l_val_;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _SYSYF_INSTRUCTION_H_
|
|
@ -1,73 +0,0 @@
|
|||||||
#ifndef _SYSYF_MODULE_H_
|
|
||||||
#define _SYSYF_MODULE_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "internal_types.h"
|
|
||||||
#include "internal_macros.h"
|
|
||||||
#include "Type.h"
|
|
||||||
#include "GlobalVariable.h"
|
|
||||||
#include "Value.h"
|
|
||||||
#include "Function.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
class GlobalVariable;
|
|
||||||
class Module;
|
|
||||||
|
|
||||||
class Module : public std::enable_shared_from_this<Module>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static Ptr<Module> create(std::string name);
|
|
||||||
~Module() = default;
|
|
||||||
|
|
||||||
Ptr<Type> get_void_type();
|
|
||||||
Ptr<Type> get_label_type();
|
|
||||||
Ptr<IntegerType> get_int1_type();
|
|
||||||
Ptr<IntegerType> get_int32_type();
|
|
||||||
Ptr<FloatType> get_float_type();
|
|
||||||
Ptr<PointerType> get_int32_ptr_type();
|
|
||||||
Ptr<PointerType> get_float_ptr_type();
|
|
||||||
|
|
||||||
Ptr<PointerType> get_pointer_type(Ptr<Type> contained);
|
|
||||||
Ptr<ArrayType> get_array_type(Ptr<Type> contained, unsigned num_elements);
|
|
||||||
|
|
||||||
void add_function(Ptr<Function> f);
|
|
||||||
PtrList<Function> &get_functions();
|
|
||||||
void add_global_variable(Ptr<GlobalVariable> g);
|
|
||||||
PtrList<GlobalVariable> &get_global_variable();
|
|
||||||
std::string get_instr_op_name( Instruction::OpID instr ) { return instr_id2string_[instr]; }
|
|
||||||
void set_print_name();
|
|
||||||
void set_file_name(std::string name){source_file_name_ = name;}
|
|
||||||
std::string get_file_name(){return source_file_name_;}
|
|
||||||
virtual std::string print();
|
|
||||||
private:
|
|
||||||
explicit Module(std::string name);
|
|
||||||
void init(std::string name);
|
|
||||||
PtrList<GlobalVariable> global_list_; // The Global Variables in the module
|
|
||||||
PtrList<Function> function_list_; // The Functions in the module
|
|
||||||
std::map<std::string, Ptr<Value>> value_sym_; // Symbol table for values
|
|
||||||
std::map<Instruction::OpID, std::string> instr_id2string_; // Instruction from opid to string
|
|
||||||
|
|
||||||
std::string module_name_; // Human readable identifier for the module
|
|
||||||
std::string source_file_name_; // Original source file name for module, for test and debug
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ptr<IntegerType> int1_ty_;
|
|
||||||
Ptr<IntegerType> int32_ty_;
|
|
||||||
Ptr<FloatType> float32_ty_;
|
|
||||||
Ptr<Type> label_ty_;
|
|
||||||
Ptr<Type> void_ty_;
|
|
||||||
|
|
||||||
std::map<Ptr<Type> , Ptr<PointerType>> pointer_map_;
|
|
||||||
std::map<std::pair<Ptr<Type> ,int>, Ptr<ArrayType> > array_map_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _SYSYF_MODULE_H_
|
|
@ -1,162 +0,0 @@
|
|||||||
#ifndef _SYSYF_TYPE_H_
|
|
||||||
#define _SYSYF_TYPE_H_
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "internal_types.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
class Module;
|
|
||||||
class IntegerType;
|
|
||||||
class FloatType;
|
|
||||||
class FunctionType;
|
|
||||||
class ArrayType;
|
|
||||||
class PointerType;
|
|
||||||
class Type;
|
|
||||||
|
|
||||||
class Type : public std::enable_shared_from_this<Type>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum TypeID {
|
|
||||||
VoidTyID, // Void
|
|
||||||
LabelTyID, // Labels, e.g., BasicBlock
|
|
||||||
IntegerTyID, // Integers, include 32 bits and 1 bit
|
|
||||||
FloatTyID, // Floats, only 32 bits
|
|
||||||
FunctionTyID, // Functions
|
|
||||||
ArrayTyID, // Arrays
|
|
||||||
PointerTyID, // Pointer
|
|
||||||
};
|
|
||||||
|
|
||||||
static Ptr<Type> create(TypeID tid, Ptr<Module> m);
|
|
||||||
|
|
||||||
~Type() = default;
|
|
||||||
|
|
||||||
TypeID get_type_id() const { return tid_; }
|
|
||||||
|
|
||||||
bool is_void_type() const { return get_type_id() == VoidTyID; }
|
|
||||||
|
|
||||||
bool is_label_type() const { return get_type_id() == LabelTyID; }
|
|
||||||
|
|
||||||
bool is_integer_type() const { return get_type_id() == IntegerTyID; }
|
|
||||||
|
|
||||||
bool is_float_type() const { return get_type_id() == FloatTyID; }
|
|
||||||
|
|
||||||
bool is_function_type() const { return get_type_id() == FunctionTyID; }
|
|
||||||
|
|
||||||
bool is_array_type() const { return get_type_id() == ArrayTyID; }
|
|
||||||
|
|
||||||
bool is_pointer_type() const { return get_type_id() == PointerTyID; }
|
|
||||||
|
|
||||||
static bool is_eq_type(Ptr<Type> ty1, Ptr<Type> ty2);
|
|
||||||
|
|
||||||
static Ptr<Type> get_void_type(Ptr<Module> m);
|
|
||||||
|
|
||||||
static Ptr<Type> get_label_type(Ptr<Module> m);
|
|
||||||
|
|
||||||
static Ptr<IntegerType> get_int1_type(Ptr<Module> m);
|
|
||||||
|
|
||||||
static Ptr<IntegerType> get_int32_type(Ptr<Module> m);
|
|
||||||
|
|
||||||
static Ptr<FloatType> get_float_type(Ptr<Module> m);
|
|
||||||
|
|
||||||
static Ptr<PointerType> get_int32_ptr_type(Ptr<Module> m);
|
|
||||||
|
|
||||||
static Ptr<PointerType> get_float_ptr_type(Ptr<Module> m);
|
|
||||||
|
|
||||||
static Ptr<PointerType> get_pointer_type(Ptr<Type> contained);
|
|
||||||
|
|
||||||
static Ptr<ArrayType> get_array_type(Ptr<Type> contained, unsigned num_elements);
|
|
||||||
|
|
||||||
Ptr<Type> get_pointer_element_type();
|
|
||||||
|
|
||||||
Ptr<Type> get_array_element_type();
|
|
||||||
|
|
||||||
int get_size();
|
|
||||||
|
|
||||||
Ptr<Module> get_module();
|
|
||||||
|
|
||||||
std::string print();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit Type(TypeID tid, Ptr<Module> m);
|
|
||||||
void init(TypeID tid, Ptr<Module> m) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
TypeID tid_;
|
|
||||||
Ptr<Module> m_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IntegerType : public Type {
|
|
||||||
public:
|
|
||||||
static Ptr<IntegerType> create(unsigned num_bits, Ptr<Module> m );
|
|
||||||
|
|
||||||
unsigned get_num_bits();
|
|
||||||
private:
|
|
||||||
explicit IntegerType(unsigned num_bits ,Ptr<Module> m);
|
|
||||||
void init(unsigned num_bits ,Ptr<Module> m) { Type::init(IntegerTyID, m); }
|
|
||||||
unsigned num_bits_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FloatType : public Type {
|
|
||||||
public:
|
|
||||||
static Ptr<FloatType> create(Ptr<Module> m);
|
|
||||||
private:
|
|
||||||
explicit FloatType(Ptr<Module> m);
|
|
||||||
void init(Ptr<Module> m) { Type::init(FloatTyID, m); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class FunctionType : public Type {
|
|
||||||
public:
|
|
||||||
static Ptr<FunctionType> create(Ptr<Type> result, PtrVec<Type> params);
|
|
||||||
static bool is_valid_return_type(Ptr<Type> ty);
|
|
||||||
static bool is_valid_argument_type(Ptr<Type> ty);
|
|
||||||
|
|
||||||
unsigned get_num_of_args() const;
|
|
||||||
|
|
||||||
Ptr<Type> get_param_type(unsigned i) const;
|
|
||||||
PtrVec<Type>::iterator param_begin() { return args_.begin(); }
|
|
||||||
PtrVec<Type>::iterator param_end() { return args_.end(); }
|
|
||||||
Ptr<Type> get_return_type() const;
|
|
||||||
private:
|
|
||||||
explicit FunctionType(Ptr<Type> result, PtrVec<Type> params);
|
|
||||||
void init(Ptr<Type> result, PtrVec<Type> params) { Type::init(FunctionTyID, nullptr); }
|
|
||||||
Ptr<Type> result_;
|
|
||||||
PtrVec<Type> args_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ArrayType : public Type {
|
|
||||||
public:
|
|
||||||
static bool is_valid_element_type(Ptr<Type> ty);
|
|
||||||
|
|
||||||
static Ptr<ArrayType> get(Ptr<Type> contained, unsigned num_elements);
|
|
||||||
static Ptr<ArrayType> create(Ptr<Type> contained, unsigned num_elements);
|
|
||||||
|
|
||||||
Ptr<Type> get_element_type() const { return contained_; }
|
|
||||||
unsigned get_num_of_elements() const { return num_elements_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit ArrayType(Ptr<Type> contained, unsigned num_elements);
|
|
||||||
void init(Ptr<Type> contained, unsigned num_elements) { Type::init(ArrayTyID, nullptr); }
|
|
||||||
Ptr<Type> contained_; // The element type of the array.
|
|
||||||
unsigned num_elements_; // Number of elements in the array.
|
|
||||||
};
|
|
||||||
|
|
||||||
class PointerType : public Type {
|
|
||||||
public:
|
|
||||||
Ptr<Type> get_element_type() const { return contained_; }
|
|
||||||
static Ptr<PointerType> get(Ptr<Type> contained);
|
|
||||||
static Ptr<PointerType> create(Ptr<Type> contained);
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit PointerType(Ptr<Type> contained);
|
|
||||||
void init(Ptr<Type> contained) { Type::init(PointerTyID, nullptr); }
|
|
||||||
Ptr<Type> contained_; // The element type of the ptr.
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // _SYSYF_TYPE_H_
|
|
@ -1,41 +0,0 @@
|
|||||||
#ifndef _SYSYF_USER_H_
|
|
||||||
#define _SYSYF_USER_H_
|
|
||||||
|
|
||||||
#include "Value.h"
|
|
||||||
#include <vector>
|
|
||||||
// #include <memory>
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
class User : public Value
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~User() = default;
|
|
||||||
|
|
||||||
PtrVec<Value>& get_operands();
|
|
||||||
|
|
||||||
// start from 0
|
|
||||||
Ptr<Value> get_operand(unsigned i) const;
|
|
||||||
|
|
||||||
// start from 0
|
|
||||||
void set_operand(unsigned i, Ptr<Value> v);
|
|
||||||
void add_operand(Ptr<Value> v);
|
|
||||||
|
|
||||||
unsigned get_num_operand() const;
|
|
||||||
|
|
||||||
void remove_use_of_ops();
|
|
||||||
void remove_operands(int index1,int index2);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit User(Ptr<Type> ty, const std::string &name = "", unsigned num_ops = 0);
|
|
||||||
|
|
||||||
private:
|
|
||||||
PtrVec<Value> operands_; // operands of this value
|
|
||||||
unsigned num_ops_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // _SYSYF_USER_H_
|
|
@ -1,63 +0,0 @@
|
|||||||
#ifndef _SYSYF_VALUE_H_
|
|
||||||
#define _SYSYF_VALUE_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "internal_types.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
|
|
||||||
class Type;
|
|
||||||
class Value;
|
|
||||||
|
|
||||||
struct Use
|
|
||||||
{
|
|
||||||
Ptr<Value> val_;
|
|
||||||
unsigned arg_no_; // the no. of operand, e.g., func(a, b), a is 0, b is 1
|
|
||||||
Use(Ptr<Value> val, unsigned no) : val_(val), arg_no_(no) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Value : public std::enable_shared_from_this<Value>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~Value() = default;
|
|
||||||
|
|
||||||
Ptr<Type> get_type() const { return type_; }
|
|
||||||
|
|
||||||
std::list<Use> &get_use_list() { return use_list_; }
|
|
||||||
|
|
||||||
void add_use(Ptr<Value> val, unsigned arg_no = 0);
|
|
||||||
|
|
||||||
bool set_name(std::string name) {
|
|
||||||
if (name_ == "")
|
|
||||||
{
|
|
||||||
name_=name;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::string get_name() const;
|
|
||||||
|
|
||||||
void replace_all_use_with(Ptr<Value> new_val);
|
|
||||||
void remove_use(Ptr<Value> val);
|
|
||||||
|
|
||||||
virtual std::string print() = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit Value(Ptr<Type> ty, const std::string &name = "");
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ptr<Type> type_;
|
|
||||||
std::list<Use> use_list_; // who use this value
|
|
||||||
std::string name_; // should we put name field here ?
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // _SYSYF_VALUE_H_
|
|
@ -1,229 +0,0 @@
|
|||||||
#ifndef _SYSYF_IR_BUILDER_H_
|
|
||||||
#define _SYSYF_IR_BUILDER_H_
|
|
||||||
#include "BasicBlock.h"
|
|
||||||
#include "Constant.h"
|
|
||||||
#include "Function.h"
|
|
||||||
#include "IRStmtBuilder.h"
|
|
||||||
#include "Module.h"
|
|
||||||
#include "Type.h"
|
|
||||||
#include <map>
|
|
||||||
#include "SyntaxTree.h"
|
|
||||||
|
|
||||||
namespace SysYF
|
|
||||||
{
|
|
||||||
namespace IR
|
|
||||||
{
|
|
||||||
class Scope {
|
|
||||||
public:
|
|
||||||
// enter a new scope
|
|
||||||
void enter() {
|
|
||||||
name2var.push_back({});
|
|
||||||
name2func.push_back({});
|
|
||||||
}
|
|
||||||
|
|
||||||
// exit a scope
|
|
||||||
void exit() {
|
|
||||||
name2var.pop_back();
|
|
||||||
name2func.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool in_global() {
|
|
||||||
return name2var.size() == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// push a name to scope
|
|
||||||
// return true if successful
|
|
||||||
// return false if this name already exits
|
|
||||||
// but func name could be same with variable name
|
|
||||||
bool push(std::string name, Ptr<Value> val) {
|
|
||||||
bool result;
|
|
||||||
if (dynamic_pointer_cast<Function>(val)){
|
|
||||||
result = (name2func[name2func.size() - 1].insert({name, val})).second;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
result = (name2var[name2var.size() - 1].insert({name, val})).second;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ptr<Value> find(std::string name, bool isfunc) {
|
|
||||||
if (isfunc){
|
|
||||||
for (auto s = name2func.rbegin(); s!= name2func.rend();s++) {
|
|
||||||
auto iter = s->find(name);
|
|
||||||
if (iter != s->end()) {
|
|
||||||
return iter->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
for (auto s = name2var.rbegin(); s!= name2var.rend();s++) {
|
|
||||||
auto iter = s->find(name);
|
|
||||||
if (iter != s->end()) {
|
|
||||||
return iter->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::map<std::string, Ptr<Value> >> name2var;
|
|
||||||
std::vector<std::map<std::string, Ptr<Value> >> name2func;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IRBuilder: public SyntaxTree::Visitor
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
void TypeConvert(Ptr<Value> origin, Ptr<Type> expected);
|
|
||||||
void BinaryExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinOp op);
|
|
||||||
void BinaryCondExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinaryCondOp op);
|
|
||||||
virtual void visit(SyntaxTree::InitVal &) override final;
|
|
||||||
virtual void visit(SyntaxTree::Assembly &) override final;
|
|
||||||
virtual void visit(SyntaxTree::FuncDef &) override final;
|
|
||||||
virtual void visit(SyntaxTree::VarDef &) override final;
|
|
||||||
virtual void visit(SyntaxTree::AssignStmt &) override final;
|
|
||||||
virtual void visit(SyntaxTree::ReturnStmt &) override final;
|
|
||||||
virtual void visit(SyntaxTree::BlockStmt &) override final;
|
|
||||||
virtual void visit(SyntaxTree::EmptyStmt &) override final;
|
|
||||||
virtual void visit(SyntaxTree::ExprStmt &) override final;
|
|
||||||
virtual void visit(SyntaxTree::UnaryCondExpr &) override final;
|
|
||||||
virtual void visit(SyntaxTree::BinaryCondExpr &) override final;
|
|
||||||
virtual void visit(SyntaxTree::BinaryExpr &) override final;
|
|
||||||
virtual void visit(SyntaxTree::UnaryExpr &) override final;
|
|
||||||
virtual void visit(SyntaxTree::LVal &) override final;
|
|
||||||
virtual void visit(SyntaxTree::Literal &) override final;
|
|
||||||
virtual void visit(SyntaxTree::FuncCallStmt &) override final;
|
|
||||||
virtual void visit(SyntaxTree::FuncParam &) override final;
|
|
||||||
virtual void visit(SyntaxTree::FuncFParamList &) override final;
|
|
||||||
virtual void visit(SyntaxTree::IfStmt &) override final;
|
|
||||||
virtual void visit(SyntaxTree::WhileStmt &) override final;
|
|
||||||
virtual void visit(SyntaxTree::BreakStmt &) override final;
|
|
||||||
virtual void visit(SyntaxTree::ContinueStmt &) override final;
|
|
||||||
|
|
||||||
Ptr<IRStmtBuilder> builder;
|
|
||||||
Scope scope;
|
|
||||||
Ptr<Module> module;
|
|
||||||
|
|
||||||
IRBuilder() {
|
|
||||||
module = Module::create("SysYF code");
|
|
||||||
builder = IRStmtBuilder::create(nullptr, module);
|
|
||||||
auto TyVoid = Type::get_void_type(module);
|
|
||||||
auto TyInt32 = Type::get_int32_type(module);
|
|
||||||
auto TyInt32Ptr = Type::get_int32_ptr_type(module);
|
|
||||||
auto TyFloat = Type::get_float_type(module);
|
|
||||||
auto TyFloatPtr = Type::get_float_ptr_type(module);
|
|
||||||
|
|
||||||
auto input_type = FunctionType::create(TyInt32, {});
|
|
||||||
auto get_int =
|
|
||||||
Function::create(
|
|
||||||
input_type,
|
|
||||||
"get_int",
|
|
||||||
module);
|
|
||||||
|
|
||||||
input_type = FunctionType::create(TyFloat, {});
|
|
||||||
auto get_float =
|
|
||||||
Function::create(
|
|
||||||
input_type,
|
|
||||||
"get_float",
|
|
||||||
module);
|
|
||||||
|
|
||||||
input_type = FunctionType::create(TyInt32, {});
|
|
||||||
auto get_char =
|
|
||||||
Function::create(
|
|
||||||
input_type,
|
|
||||||
"get_char",
|
|
||||||
module);
|
|
||||||
|
|
||||||
PtrVec<Type> input_params;
|
|
||||||
PtrVec<Type> ().swap(input_params);
|
|
||||||
input_params.push_back(TyInt32Ptr);
|
|
||||||
input_type = FunctionType::create(TyInt32, input_params);
|
|
||||||
auto get_int_array =
|
|
||||||
Function::create(
|
|
||||||
input_type,
|
|
||||||
"get_int_array",
|
|
||||||
module);
|
|
||||||
|
|
||||||
PtrVec<Type> ().swap(input_params);
|
|
||||||
input_params.push_back(TyFloatPtr);
|
|
||||||
input_type = FunctionType::create(TyInt32, input_params);
|
|
||||||
auto get_float_array =
|
|
||||||
Function::create(
|
|
||||||
input_type,
|
|
||||||
"get_float_array",
|
|
||||||
module);
|
|
||||||
|
|
||||||
PtrVec<Type> output_params;
|
|
||||||
PtrVec<Type> ().swap(output_params);
|
|
||||||
output_params.push_back(TyInt32);
|
|
||||||
auto output_type = FunctionType::create(TyVoid, output_params);
|
|
||||||
auto put_int =
|
|
||||||
Function::create(
|
|
||||||
output_type,
|
|
||||||
"put_int",
|
|
||||||
module);
|
|
||||||
|
|
||||||
PtrVec<Type> ().swap(output_params);
|
|
||||||
output_params.push_back(TyFloat);
|
|
||||||
output_type = FunctionType::create(TyVoid, output_params);
|
|
||||||
auto put_float =
|
|
||||||
Function::create(
|
|
||||||
output_type,
|
|
||||||
"put_float",
|
|
||||||
module);
|
|
||||||
|
|
||||||
PtrVec<Type> ().swap(output_params);
|
|
||||||
output_params.push_back(TyInt32);
|
|
||||||
output_type = FunctionType::create(TyVoid, output_params);
|
|
||||||
auto put_char =
|
|
||||||
Function::create(
|
|
||||||
output_type,
|
|
||||||
"put_char",
|
|
||||||
module);
|
|
||||||
|
|
||||||
PtrVec<Type> ().swap(output_params);
|
|
||||||
output_params.push_back(TyInt32);
|
|
||||||
output_params.push_back(TyInt32Ptr);
|
|
||||||
output_type = FunctionType::create(TyVoid, output_params);
|
|
||||||
auto put_int_array =
|
|
||||||
Function::create(
|
|
||||||
output_type,
|
|
||||||
"put_int_array",
|
|
||||||
module);
|
|
||||||
|
|
||||||
PtrVec<Type> ().swap(output_params);
|
|
||||||
output_params.push_back(TyInt32);
|
|
||||||
output_params.push_back(TyFloatPtr);
|
|
||||||
output_type = FunctionType::create(TyVoid, output_params);
|
|
||||||
auto put_float_array =
|
|
||||||
Function::create(
|
|
||||||
output_type,
|
|
||||||
"put_float_array",
|
|
||||||
module);
|
|
||||||
|
|
||||||
scope.enter();
|
|
||||||
scope.push("getint", get_int);
|
|
||||||
scope.push("getfloat", get_float);
|
|
||||||
scope.push("getch", get_char);
|
|
||||||
scope.push("getarray", get_int_array);
|
|
||||||
scope.push("get_float_array", get_float_array);
|
|
||||||
scope.push("putint", put_int);
|
|
||||||
scope.push("putfloat", put_float);
|
|
||||||
scope.push("putch", put_char);
|
|
||||||
scope.push("putarray", put_int_array);
|
|
||||||
scope.push("putfloatarray", put_float_array);
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
static Ptr<IRBuilder> create() {
|
|
||||||
return Ptr<IRBuilder>(new IRBuilder());
|
|
||||||
}
|
|
||||||
Ptr<Module> getModule() {
|
|
||||||
return module;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _SYSYF_IR_BUILDER_H_
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue