Skip to content

neroll-2021/compiler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

107 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Compiler

Compiler 是一个基于 LLVM 的编译器,用于编译自创的静态类型编程语言 lyris 。

快速开始

前置依赖

  • xmake xmake 是一个基于Lua的轻量级跨平台自动构建工具,并自带强大的包管理和集成功能。
  • clang 本项目将 lyris 代码编译为 LLVM IR,由 clang 将 IR 编译链接成可执行文件。
  • llvm 部分代码需要使用 llvm 工具链,windows 上的 mingw 自带 llvm 工具链。

操作系统支持:windows,linux

编译运行

拉取代码后,在项目根目录输入以下命令编译项目:

xmake

编译时需要安装 llvm、boost 等依赖库,若出现提示请输入 y。如果下载因网络问题失败,考虑使用 VPN,并参考 官方文档

编译完成后,输入以下命令即可运行项目:

xmake run compiler -o bin/main code/main.txt

这条命令会编译 code/main.txt 代码文件,并在 bin 目录下生成名为 main 的可执行文件。随后运行可执行文件,将看到输出 hello world!

要了解更多用法,使用以下命令打印编译器帮助列表

xmake run compiler --help

测试

在项目根目录输入以下命令开始测试

xmake test

在 test/code 目录下有用于测试的代码文件,这些代码文件可以帮助理解 lyris 的使用。

安装

要安装 Compiler,首先需要在项目根目录下运行以下命令

xmake f --dev=false
xmake install -o <install directory>

第二条命令中的 <install directory> 替换为安装目录。

安装完成后将在安装目录看到以下结构的文件

./compiler/
├── bin
│   └── compiler
├── include
│   └── io
└── lib
    └── libio.a

bin:存放编译器的可执行文件

include:保存 lyris 需要的标准库函数

lib:标准库函数的依赖库,包含标准库函数的具体实现

将 bin 目录加入到 PATH 环境变量中,就可以像 gcc、clang 一样使用 Compiler 了。

Lyris

简介

lyris 是一门静态类型的编译型语言。它有三个基本类型:int, boolean, string,这三个基本类型可以组成数组和结构体。lyris 支持条件语句、循环语句、函数、嵌套作用域、导入库函数。lyris 没有类型转换,编译器会检查类型的使用是否正确。

以下是使用 lyris 输出 hello world! 的代码:

import io;

func main() -> int {
    printf("hello world!\n");
    return 0;
}

import io 表明要导入 io 库函数。io 库中声明了 printf 函数,这个函数的用法和 C 语言中的一样。

func 关键字用于指示函数声明或函数定义。这里定义了一个 main 函数,箭头(->)后的 int 表示返回类型。一份 lyris 代码必须包含 main 函数。

变量

lyris 使用 let 关键字声明变量,随后是变量名,后面是类型名称,最后是可选的初始化。

lyris 支持自动类型推导,当变量被初始化时,可以省略变量类型。

变量之间可以赋值,前提是赋值运算符两侧的操作数类型一致。

func main() -> int {
    let a : int;
    let b : int = 10;
    let c = 30;
    let d : boolean = true;
    let e : string = "hello";
    e = "world!";
    return 0;
}

条件语句

lyris 使用 ifelse 实现条件语句,这一点和 C 语言一样,不同之处在于 if 条件只能是 boolean 类型。

import io;
func main() -> int {
    let x = input();
    if (x < 10) {
        printf("x is less than 10\n");
    } else if (x > 10) {
        printf("x is greater than 10\n");
    } else {
        printf("x is 10\n"); 
    }
    return 0;
}

循环语句

lyris 支持 for 循环和 while 循环,语法和 C 语言相同。

func main() -> int {
    for (let i = 0; i < 10; i++) {
        println(i);
    }
    return 0;
}

结构体

lyris 支持结构体。结构体有多个成员组成,成员类型可以是基本类型,也可以是结构体,但不能是数组。一个结构体最多有 255 个成员。

struct Pair {
    let x : int;
    let y : int;
}

结构体成员并不是变量声明,所以不能初始化,也不能省略类型。

使用 . 访问结构体变量的成员

func main() -> int {
    let pair : Pair;
    pair.x = 10;
    pair.y = 20;
    println(pair.y);
    return 0;
}

结构体之间可以直接赋值。

数组

数组可以看成由一个或多个连续存放的变量。lyris 中定义数组只需在类型名后用中括号和数字指定数组大小。

func main() -> int {
    let a : int[10];
    let b : boolean[2];
    return 0;
}

数组大小只能是整型字面量,不能是变量,且数组类型的变量不能初始化。

数组元素可以是基本类型,也可以是结构体。

数组类型由元素类型和数组大小构成,因此不同大小的数组是不同的类型。

数组之间无法赋值。

使用中括号和整数访问数组元素

func main() -> int {
    let a : int[10];
    a[0] = 1;
    a[1] = a[0];
    return 0;
}

函数

函数必须有返回值,且函数体必须有 return。

函数可以返回结构体,但不能返回数组。

函数可以接收最多 255 个参数,参数类型可以是结构体,但不能是数组。lyris 中函数参数都是值传递,函数无法修改实参。

struct Pair {
    let x : int;
    let y : int;
}

func make_pair(int x, int y) -> Pair {
    let p : Pair;
    p.x = x;
    p.y = y;
    return p;
}

func swap(Pair x) -> Pair {
    let p : Pair;
    p.x = x.y;
    p.y = x.x;
    return p;
}

内置函数:

  • print 打印一个整数
  • println 打印一个整数并换行
  • input 从标准输入接收一个整数,并返回
  • puts 输出字符串并返回
  • printf 格式化输出字符串
  • print_boolean 打印布尔值并换行

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors