parent
							
								
									a59efbf0e2
								
							
						
					
					
						commit
						36f4d12287
					
				@ -0,0 +1,3 @@
 | 
				
			||||
 .vscode
 | 
				
			||||
 build
 | 
				
			||||
 
 | 
				
			||||
@ -0,0 +1,37 @@
 | 
				
			||||
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 -Werror -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
 | 
				
			||||
)
 | 
				
			||||
@ -0,0 +1,28 @@
 | 
				
			||||
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];
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,51 @@
 | 
				
			||||
; 中间代码头部尾部参考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"}
 | 
				
			||||
@ -0,0 +1,6 @@
 | 
				
			||||
int main(){
 | 
				
			||||
    float b = 1.8;
 | 
				
			||||
    int a[2] = {2};
 | 
				
			||||
    a[1] = a[0] * b;
 | 
				
			||||
    return a[1];
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,13 @@
 | 
				
			||||
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);
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,9 @@
 | 
				
			||||
int a;
 | 
				
			||||
 | 
				
			||||
int main(){
 | 
				
			||||
	a = 10;
 | 
				
			||||
	if( a>0 ){
 | 
				
			||||
		return a;
 | 
				
			||||
	}
 | 
				
			||||
	return 0;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,11 @@
 | 
				
			||||
int a;
 | 
				
			||||
int b;
 | 
				
			||||
int main(){
 | 
				
			||||
	b=0;
 | 
				
			||||
	a=3;
 | 
				
			||||
	while(a>0){	
 | 
				
			||||
		b = b+a;
 | 
				
			||||
		a = a-1;
 | 
				
			||||
	}
 | 
				
			||||
	return b;
 | 
				
			||||
}	
 | 
				
			||||
@ -0,0 +1,18 @@
 | 
				
			||||
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)
 | 
				
			||||
@ -0,0 +1,36 @@
 | 
				
			||||
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
 | 
				
			||||
)
 | 
				
			||||
  
 | 
				
			||||
@ -0,0 +1,3 @@
 | 
				
			||||
int main(){
 | 
				
			||||
    return 0;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,3 @@
 | 
				
			||||
int main(){
 | 
				
			||||
    return 0;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,3 @@
 | 
				
			||||
int main(){
 | 
				
			||||
    return 0;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,3 @@
 | 
				
			||||
int main(){
 | 
				
			||||
    return 0;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,8 @@
 | 
				
			||||
add_executable(
 | 
				
			||||
    go_upstairs_generator
 | 
				
			||||
    go_upstairs_gen.cpp
 | 
				
			||||
)
 | 
				
			||||
target_link_libraries(
 | 
				
			||||
    go_upstairs_generator
 | 
				
			||||
    IRLib
 | 
				
			||||
)
 | 
				
			||||
@ -0,0 +1,28 @@
 | 
				
			||||
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];
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,6 @@
 | 
				
			||||
int main(){
 | 
				
			||||
    float b = 1.8;
 | 
				
			||||
    int a[2] = {2};
 | 
				
			||||
    a[1] = a[0] * b;
 | 
				
			||||
    return a[1];
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,13 @@
 | 
				
			||||
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);
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,9 @@
 | 
				
			||||
int a;
 | 
				
			||||
 | 
				
			||||
int main(){
 | 
				
			||||
	a = 10;
 | 
				
			||||
	if( a>0 ){
 | 
				
			||||
		return a;
 | 
				
			||||
	}
 | 
				
			||||
	return 0;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,11 @@
 | 
				
			||||
int a;
 | 
				
			||||
int b;
 | 
				
			||||
int main(){
 | 
				
			||||
	b=0;
 | 
				
			||||
	a=3;
 | 
				
			||||
	while(a>0){	
 | 
				
			||||
		b = b+a;
 | 
				
			||||
		a = a-1;
 | 
				
			||||
	}
 | 
				
			||||
	return b;
 | 
				
			||||
}	
 | 
				
			||||
@ -0,0 +1,92 @@
 | 
				
			||||
#!/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:
 | 
				
			||||
                    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)
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
0
 | 
				
			||||
@ -0,0 +1,3 @@
 | 
				
			||||
int main(){
 | 
				
			||||
	return 0;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
29
 | 
				
			||||
@ -0,0 +1,8 @@
 | 
				
			||||
int a,b;
 | 
				
			||||
 | 
				
			||||
int main(){
 | 
				
			||||
    a=10;
 | 
				
			||||
    b=5;
 | 
				
			||||
    int c=a*2+b*1.1+3.6;
 | 
				
			||||
    return c;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
21
 | 
				
			||||
@ -0,0 +1,5 @@
 | 
				
			||||
int main() {
 | 
				
			||||
  int a = 10;
 | 
				
			||||
  ;
 | 
				
			||||
  return a * 2 + 1;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
0
 | 
				
			||||
@ -0,0 +1,4 @@
 | 
				
			||||
int a[10];
 | 
				
			||||
int main(){
 | 
				
			||||
	return 0;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
0
 | 
				
			||||
@ -0,0 +1,5 @@
 | 
				
			||||
int a[10];
 | 
				
			||||
int main(){
 | 
				
			||||
	a[0]=1;
 | 
				
			||||
	return 0;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
4
 | 
				
			||||
@ -0,0 +1,5 @@
 | 
				
			||||
const int x=4;
 | 
				
			||||
 | 
				
			||||
int main(){
 | 
				
			||||
    return x;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
8
 | 
				
			||||
@ -0,0 +1,7 @@
 | 
				
			||||
const int a[5]={0,1,2,3,4};
 | 
				
			||||
const int b = 3;
 | 
				
			||||
float c = a[b + 1];
 | 
				
			||||
 | 
				
			||||
int main(){
 | 
				
			||||
    return a[4] + c;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
4
 | 
				
			||||
@ -0,0 +1,8 @@
 | 
				
			||||
int defn(){
 | 
				
			||||
    return 4;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
int main(){
 | 
				
			||||
    int a=defn();
 | 
				
			||||
    return a;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
5
 | 
				
			||||
@ -0,0 +1,13 @@
 | 
				
			||||
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;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
1
 | 
				
			||||
@ -0,0 +1,9 @@
 | 
				
			||||
int a;
 | 
				
			||||
 | 
				
			||||
int main(){
 | 
				
			||||
	a = 10;
 | 
				
			||||
	if( a>0 ){
 | 
				
			||||
		return 1;
 | 
				
			||||
	}
 | 
				
			||||
	return 0;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
1
 | 
				
			||||
@ -0,0 +1,10 @@
 | 
				
			||||
int a;
 | 
				
			||||
int main(){
 | 
				
			||||
	a = 10;
 | 
				
			||||
	if( a>0 ){
 | 
				
			||||
		return 1;
 | 
				
			||||
	}
 | 
				
			||||
	else{
 | 
				
			||||
		return 0;
 | 
				
			||||
	}
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
6
 | 
				
			||||
@ -0,0 +1,11 @@
 | 
				
			||||
int a;
 | 
				
			||||
int b;
 | 
				
			||||
int main(){
 | 
				
			||||
	b=0;
 | 
				
			||||
	a=3;
 | 
				
			||||
	while(a>0){	
 | 
				
			||||
		b = b+a;
 | 
				
			||||
		a = a-1;
 | 
				
			||||
	}
 | 
				
			||||
	return b;
 | 
				
			||||
}	
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
5
 | 
				
			||||
@ -0,0 +1,9 @@
 | 
				
			||||
int main(){
 | 
				
			||||
    int a=10;
 | 
				
			||||
    while(a>0){
 | 
				
			||||
        a=a-1;
 | 
				
			||||
        if(a==5)
 | 
				
			||||
            break;
 | 
				
			||||
    }
 | 
				
			||||
    return a;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
5
 | 
				
			||||
@ -0,0 +1,11 @@
 | 
				
			||||
int main(){
 | 
				
			||||
    int a=10;
 | 
				
			||||
    while(a>0){
 | 
				
			||||
        if(a>5){
 | 
				
			||||
            a=a-1;
 | 
				
			||||
            continue;
 | 
				
			||||
        }
 | 
				
			||||
        return a;
 | 
				
			||||
    }
 | 
				
			||||
    return a;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
10
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
10
 | 
				
			||||
@ -0,0 +1,5 @@
 | 
				
			||||
int main(){
 | 
				
			||||
	int a;
 | 
				
			||||
	a = getint();
 | 
				
			||||
	return a;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
5
 | 
				
			||||
@ -0,0 +1,23 @@
 | 
				
			||||
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));
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
3 2
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
0
 | 
				
			||||
@ -0,0 +1,12 @@
 | 
				
			||||
int a;
 | 
				
			||||
int b;
 | 
				
			||||
int main(){
 | 
				
			||||
	a = getint();
 | 
				
			||||
	b = getint();
 | 
				
			||||
	if ( a == b ){
 | 
				
			||||
		return 1;
 | 
				
			||||
	}
 | 
				
			||||
	else{
 | 
				
			||||
		return 0;
 | 
				
			||||
	}
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
8
 | 
				
			||||
@ -0,0 +1,17 @@
 | 
				
			||||
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;
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,2 @@
 | 
				
			||||
4
 | 
				
			||||
20
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
4
 | 
				
			||||
@ -0,0 +1,34 @@
 | 
				
			||||
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);
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,5 @@
 | 
				
			||||
4
 | 
				
			||||
4
 | 
				
			||||
7
 | 
				
			||||
3
 | 
				
			||||
9
 | 
				
			||||
@ -0,0 +1,5 @@
 | 
				
			||||
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
 | 
				
			||||
@ -0,0 +1,27 @@
 | 
				
			||||
 | 
				
			||||
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.
											
										
									
								| 
		 After Width: | Height: | Size: 30 KiB  | 
@ -0,0 +1,330 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,43 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,29 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,225 @@
 | 
				
			||||
// -*-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
 | 
				
			||||
 | 
				
			||||
@ -0,0 +1,50 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,37 @@
 | 
				
			||||
#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
												
											
										
									
								@ -0,0 +1,304 @@
 | 
				
			||||
// 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
 | 
				
			||||
@ -0,0 +1,11 @@
 | 
				
			||||
// 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"
 | 
				
			||||
@ -0,0 +1,8 @@
 | 
				
			||||
// 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.
 | 
				
			||||
@ -0,0 +1,86 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,90 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,110 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,31 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,25 @@
 | 
				
			||||
#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
 | 
				
			||||
@ -0,0 +1,84 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,435 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,73 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,162 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,41 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,63 @@
 | 
				
			||||
#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_
 | 
				
			||||
@ -0,0 +1,226 @@
 | 
				
			||||
#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:
 | 
				
			||||
    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