summaryrefslogtreecommitdiff
path: root/README.md
blob: 75827a92c21ea70dd1625aecbb4117c3f90c4a6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# pcc - simple pascal-like compiler based on LLVM

## How to build

### linux & macOS & FreeBSD

- download the LLVM 10.0.0 prebuilt binary at [LLVM release page](https://releases.llvm.org/download.html#10.0.0)
- extract the tarball
- make a build directory under the source directory
- run `cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/path/to/the/llvm/`
- run `cmake --build . -j8`

### windows

- get the awesome package manager [vcpkg](https://github.com/Microsoft/vcpkg)
- run .\vcpkg.exe install llvm:x64-windows
- make a build directory under the source directory
- run `cmake .. -DCMAKE_TOOLCHIAN_FILE=/path/to/your/vcpkg/toolchain/file`
- run `cmake --build . -j8`

### How to run

```
Usage: pcc [-vVhiScad] [-O <0,1,2,3>] [-o <output>] file...
    -v            Verbose mode.
    -vv           Very verbose mode.
    -V            Show version and exit.
    -h            Show this help and exit.

    -i            Generate LLVM IR (default behavior).
    -S            Compile to assembly file.
    -c            Compile to object file.
    -o <output>   Specify output file name.
    -O <0,1,2,3>  Specify optimization level.

    -a            Dump the AST.
    -d            Generate a dot file for AST.
```

You can find some examples at the t directory.

#### compile pascal file to executable

```
./pcc -c qsort.pas
```

Then you need to link the object file qsort.o by your host-compiler.

- gcc case: `gcc -no-pie qsort.o`
- clang case: `clang qsort.o`
- msvc case: find the developer command window, use cl to link

#### calling C functions from pascal

See ssl.pas and extern.pas.

For the `scanf` case, the `scanf` may be a marco in C like `__isoc99_scanf`, so you may need to wrap the scanf function, see common.pas.

#### calling pascal functions from C

See sha1.pas and sha1_driver.pas.

### How to get the tree or graph view of AST

pass -a to pcc, you will get a tree view of AST like this:

```
  `-FunctionNode FunctionName=main ReturnType=integer
    |-VarDeclNode local size=2
    | |-Variable name=arr type=integer[100000]
    | `-Variable name=i type=integer
    `-StatementListNode size=5
      |-FunctionCallNode FunctionName=srand ResultType=void
      | `-FunctionCallNode FunctionName=time ResultType=integer
      |   `-IntegerLiteralNode value=0
      |-ForStatementNode direction=up
      | |-IdentifierNode lvalue name=i type=^integer
      | |-IntegerLiteralNode value=0
      | |-IntegerLiteralNode value=99999
      | `-AssignStatementNode ValueType=int64
      |   |-ArrayAccessNode ResultType=^integer
      |   | |-IdentifierNode lvalue name=arr type=^integer[100000]
      |   | `-L2RCastingNode ResultType=integer
      |   |   `-IdentifierNode lvalue name=i type=^integer
      |   `-BinaryExprNode op='%' ResultType=int64
      |     |-FunctionCallNode FunctionName=rand ResultType=integer
      |     `-IntegerLiteralNode value=1000
      |-FunctionCallNode FunctionName=qsort ResultType=void
      | |-IdentifierNode lvalue name=arr type=^integer[100000]
      | |-IntegerLiteralNode value=0
      | `-IntegerLiteralNode value=99999
      |-ForStatementNode direction=down
      | |-IdentifierNode lvalue name=i type=^integer
      | |-IntegerLiteralNode value=99999
      | |-IntegerLiteralNode value=0
      | `-FunctionCallNode FunctionName=printf ResultType=integer
      |   |-StringLiteralNode value='%d \x00'
      |   `-L2RCastingNode ResultType=integer
      |     `-ArrayAccessNode ResultType=^integer
      |       |-IdentifierNode lvalue name=arr type=^integer[100000]
      |       `-L2RCastingNode ResultType=integer
      |         `-IdentifierNode lvalue name=i type=^integer
      `-AssignStatementNode ValueType=int64
        |-IdentifierNode lvalue name=main type=^integer
        `-IntegerLiteralNode value=0
```

pass -d to pcc, it will generate a dot file, use graphviz to render it.

```
pcc -d qsort.pas
dot -Tpng -o qsort.png qsort.dot
```