New project

main
channa 8 months ago
commit f23a84e409

@ -0,0 +1,5 @@
Manifest-Version: 0.0.1
Project-Name: minipas
Source: src/main/rascal
Require-Libraries:

@ -0,0 +1,18 @@
# A compiler for MiniPas using Rascal
* In my compiler construction subject, we made a compiler for a language called
`MiniPas` (a subset of `Pascal`) in C. It generates LLIR code from a `.pas`
file.
## Grammar
* The grammar of the langauge can be found in `src/Syntax.rsc`. We make some
comments here.
* Since `MiniPas` has notions of both functions and procedures, we refer to either
as a `SubProg`.
* Keywords are case insensitive but identifiers are case sensitive.
## Acknowledgements
* The grammar of `MiniPas` is from the course `Compiler Construction` in the University of Groningen.
The programs in `test/input` for `MiniPas` are from this course as well.
* The structure of the `Rascal` code comes from the course `Software Language Engineering` in the University of Groningen

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.rascalmpl</groupId>
<artifactId>minipas</artifactId>
<version>0.1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>usethesource</id>
<url>https://releases.usethesource.io/maven/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>usethesource</id>
<url>https://releases.usethesource.io/maven/</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.rascalmpl</groupId>
<artifactId>rascal</artifactId>
<version>0.34.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<compilerArgument>-parameters</compilerArgument>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.rascalmpl</groupId>
<artifactId>rascal-maven-plugin</artifactId>
<version>0.8.2</version>
<configuration>
<errorsAsWarnings>true</errorsAsWarnings>
<bin>${project.build.outputDirectory}</bin>
<srcs>
<src>${project.basedir}/src/main/rascal</src>
</srcs>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,55 @@
module Syntax
extend lang::std::Layout;
extend lang::std::Id;
extend lang::std::ASCII;
start syntax Progarm = 'program' Id ";" ConstDecl* VarDecl* SubProgDecl* CompoundStatement;
syntax ConstDecl = 'const' Id "=" Number;
syntax IdList = Id {"," Id}*;
syntax TypeSpec = BasicType | 'array' "[" Number ".." Number "]" 'of' BasicType;
syntax BasicType = 'integer' | 'real';
syntax SubProgDecl = 'function' Id Parameters ":" BasicType ";" VarDecl* CompoundStatement ";" |
'procedure' Id Parameters? ";" VarDecl* CompoundStatement ";"
;
syntax Parameters = "(" ParameterList ")";
syntax ParameterList = 'var'? IdList ":" TypeSpec {";" ParameterList}*;
syntax CompoundStatement = 'begin' StatementList? 'end';
syntax StatementList = Statement {";" Statement}*;
syntax Statement = Lhs ":=" Expr |
ProcedureCall |
CompoundStatement |
'skip' |
'if' Guard 'then' Statement 'else' Statement |
'while' Guard 'do' Statement
;
syntax Guard = Expr Relop Expr |
'not' Guard |
Guard 'or' Guard |
Guard 'and' GUard |
"(" Guard ")"
;
syntax LhsList = Lhs {"," Lhs}*;
syntax Lhs = Id ("[" ExprList "]")?;
syntax ProcedureCall = Id ("(" ExprList ")")? |
'readln'"(" LhsList ")" |
'writeln'"(" ExprList ")"
;
syntax ExprList = Expr {"," Expr}*;
syntax Expr = Id ("[" Expr (".." Expr)?"]")? |
Num |
Id "(" ExprList ")" |
Expr "+" Expr |
Expr "-" Expr |
Expr "*" Expr |
Expr "/" Expr |
Expr 'div' Expr |
Expr 'mod' Expr |
"-" Expr |
"(" Expr ")"
;
lexical Relop = "\<"|"\<="|"\>"|"\>="|"=="|"!=";
lexical Number = Digit* ("." Digit+)?;

@ -0,0 +1,18 @@
module MyTest
import ParseTree;
void main() {
[loc] files = getFilesIn(|project://test/input|);
for (loc file <- files) {
runTestOn(file);
}
}
void runTestOn(loc file) {
println(file);
}
void getFilesIn(loc dir) {
return |project://test/input/arr.pas|;
}

@ -0,0 +1,24 @@
{ This program does some work on arrays, passing them by value and by reference and such }
program arr;
const N = 5;
var arr : array [5 .. 6] of real;
function some (rra : array [1 .. 2] of real; y : real; z : real) : real;
begin
some := rra[1] + y + z
end;
procedure some2 (var rra : array [2 .. 3] of real);
begin
rra[3] := rra[3] + 20
end;
begin
readln(arr[5], arr[6]);
writeln(some(arr, arr[5], N));
writeln(some(arr, 5, 5.6));
some2(arr);
writeln(arr[5], arr[6])
end.

@ -0,0 +1,32 @@
{ Example from the lab pdf }
PROGRAM arrparmechanism;
VAR a : ARRAY [0 .. 5] OF integer; {array with values a[0], a[1], a[2], a[3], a[4], a[5]}
VAR b : ARRAY [1 .. 6] OF integer; {array with values b[1], b[2], b[3], b[4], b[5], b[6]}
PROCEDURE arrcopy(VAR dest : ARRAY [0 .. 5] OF integer; src : ARRAY [5 .. 10] OF integer);
{dest is a var-paremeter, src is a value-parameter. Note the funny array bounds!}
VAR i : integer;
BEGIN
i := 0
; WHILE i <> 6 DO
BEGIN
dest[i] := src[i+5] { reflected to caller: dest is a var-parameter!}
; src[i+5] := 0 { not reflected to caller: src is a value-parameter!}
; i := i + 1
END
END;
FUNCTION sum(a : ARRAY [1 .. 3] OF integer) : integer;
BEGIN
sum := a[1] + a[2] + a[3]
END;
BEGIN
readln(b[1], b[2], b[3], b[4], b[5], b[6])
; arrcopy(a,b) {here index range translation takes place, the range sizes fit }
; writeln(a[0],a[1],a[2],a[3],a[4],a[5]) {this will print: 1 2 3 4 5 6 }
; writeln(b[1],b[2],b[3],b[4],b[5],b[6]) {this will also print: 1 2 3 4 5 6 }
; writeln(sum(a[0..2])) { note the section notation: this will print 6 (because 1+2+3=6) }
; writeln(sum(a[1..3])) { note the section notation: this will print 9 (because 2+3+4=9) }
END.

@ -0,0 +1,16 @@
{ This program tries some logic statements }
program logic;
var x, z : integer;
var xs : array [1 .. 10] of integer;
var y : real;
var ys : array [1 .. 10] of real;
begin
readln(x, xs[1], y, ys[1]);
if x < 10 and xs[1] < 1 or not(y > 0 and ys[1] >= 3 and y < 2.3 and ys[1] < 3.3) then
z := 100
else
z := 999;
writeln(z)
end.

@ -0,0 +1,33 @@
program sign;
const N = 4;
const M = 2.3;
var x, y, xy, xyz : integer;
var z : real;
var as, cs : array [2 .. 2] of real; { Array of size 1 }
var bs : array [2 .. 2] of integer;
begin
as[2] := 25.3; { assign real to *real* }
as[2] := 2; { assign int to *real* }
bs[2] := 1;
cs[2] := bs[2];
as[2] := cs[2];
x := N;
z := M;
z := 3 / 2;
z := 3.5 * 3 + 2 - 1;
z := 3.4 / 5;
z := 3.5 / 3.4 - 3.4;
y := 3 div 2;
z := bs[2];
x := 42;
y := -1;
xy := x*y;
xyz := -1*x + (-xy);
x := -x - x;
z := as[2];
writeln(z);
writeln(10 * 3 / 2 + 6 - 5 / 4 + (4 / 3 * 8 + 6 - 7) * 25 - 15 + 4)
end.

@ -0,0 +1,52 @@
program fibonacci;
var n,i : integer;
var fibs : array [1 .. 35] of integer;
function fib(n : integer) : integer;
begin
if n <= 2 then
fib := 1
else
fib := fib(n-1) + fib(n-2)
end;
function fibMem(n : integer) : integer;
var fibCache : array [1 .. 100] of integer;
var i : integer;
begin
if n > 100 then
fibMem := 0
else
begin
fibCache[1] := 1;
fibCache[2] := 1;
i := 3;
while i <= n do
begin
fibCache[i] := fibCache[i - 1] + fibCache[i - 2];
i := i + 1
end;
fibMem := fibCache[i-1]
end
end;
begin
readln(n);
i := 1;
while i <= n do
begin
writeln(fib(i));
i := i + 1
end;
{ the dynamic }
writeln(fibMem(35));
{ now for the array }
i := 1;
while i <= 35 do
begin
fibs[i] := fib(i);
i := i + 1
end;
writeln(fibs[35])
end.

@ -0,0 +1,41 @@
{ This program computes the greatest common divisor in three different ways }
PROGRAM euclid;
VAR a,b : integer;
function gcd_euclid(a, b : integer) : integer;
begin
while a <> b do
begin
while a > b do a := a - b;
while b > a do b := b - a
end;
gcd_euclid := a
end;
FUNCTION gcd_recursive(u, v : integer) : integer;
BEGIN
IF u mod v <> 0 THEN
gcd_recursive := gcd_recursive(v, u mod v)
ELSE
gcd_recursive := v
END;
function gcd_iterative(u, v : integer) : integer;
var t : integer;
begin
while v <> 0 do
begin
t := u;
u := v;
v := t mod v
end;
gcd_iterative := u
end;
BEGIN
readln(a,b);
writeln(gcd_recursive(a,b));
writeln(gcd_iterative(a,b));
writeln(gcd_euclid(a,b))
END.

@ -0,0 +1,12 @@
{ Example program implementing some old IP assignment }
PROGRAM alt;
var shift : integer;
begin
readln(shift);
if shift < 0 then
shift := shift + shift
else
shift := shift - shift;
writeln(shift)
end
.

@ -0,0 +1,63 @@
{ Example program implementing an old IP assignment that uses arrays by reference }
PROGRAM calc;
{
Small calculator with 4 registers
<register> : integer [1..4]
<value> : real
Options:
- 0 exit
- 1 <register> <value> : assign value to register
- 2 <ra> <rb> <rc> store (rb + rc) in ra (registers)
- 3 <ra> <rb> <rc> store (rb * rc) in ra (registers)
}
var rt : real;
var r : array [1 .. 4] of real;
var option, rid1, rid2, rid3 : integer;
function readRegister(var regs : array [1 .. 4] of real; regId : integer) : real;
begin
if regId >= 1 and regId <= 4 then
readRegister := regs[regId]
else
readRegister := 0
end;
procedure writeRegister(var regs : array [1 .. 4] of real; regId : integer; number : real);
begin
if regId >= 1 and regId <= 4 then
regs[regId] := number
else
skip
end;
begin
r[1] := 0;
r[2] := 0;
r[3] := 0;
r[4] := 0;
writeln(r[1], r[2], r[3], r[4]);
readln(option);
while option <> 0 do
begin
if option <= 1 then
begin
readln(rid1, rt);
writeRegister(r, rid1, rt)
end
else if option <= 2 then
begin
readln(rid1, rid2, rid3);
writeRegister(r, rid1, readRegister(r, rid2) + readRegister(r, rid3))
end
else if option <= 3 then
begin
readln(rid1, rid2, rid3);
writeRegister(r, rid1, readRegister(r, rid2) * readRegister(r, rid3))
end
else skip;
writeln(r[1], r[2], r[3], r[4]);
readln(option)
end
end
.

@ -0,0 +1,75 @@
{ Example program implementing an old IP assignment that uses arrays by reference }
PROGRAM calc;
{
Small calculator with 4 registers
<register> : integer [1..4]
<value> : real
Options:
- 0 exit
- 1 <register> <value> : assign value to register
- 2 <ra> <rb> <rc> store (rb + rc) in ra (registers)
- 3 <ra> <rb> <rc> store (rb * rc) in ra (registers)
}
var r1, r2, r3, r4, rt: real;
var option, rid1, rid2, rid3 : integer;
function readRegister(regId : integer) : real;
begin
if regId <= 1 then
readRegister := r1
else if regId <= 2 then
readRegister := r2
else if regId <= 3 then
readRegister := r3
else if regId <= 4 then
readRegister := r4
else
readRegister := 0.0
end;
procedure writeRegister(regId : integer; number : real);
begin
if regId < 1 then
skip
else if regId <= 1 then
r1 := number
else if regId <= 2 then
r2 := number
else if regId <= 3 then
r3 := number
else if regId <= 4 then
r4 := number
else skip
end;
begin
r1 := 0.0;
r2 := 0.0;
r3 := 0.0;
r4 := 0.0;
writeln(r1, r2, r3, r4);
readln(option);
while option <> 0 do
begin
if option <= 1 then
begin
readln(rid1, rt);
writeRegister(rid1, rt)
end
else if option <= 2 then
begin
readln(rid1, rid2, rid3);
writeRegister(rid1, readRegister(rid2) + readRegister(rid3))
end
else if option <= 3 then
begin
readln(rid1, rid2, rid3);
writeRegister(rid1, readRegister(rid2) * readRegister(rid3))
end
else skip;
writeln(r1, r2, r3, r4);
readln(option)
end
end
.

@ -0,0 +1,21 @@
{ Example IP exam assignment with a basic while loop }
program missing;
{ Takes a number N, then N unique numbers <= N of which one is 0. Prints the missing number <= N }
var n, total, a, i : integer;
begin
readln(n);
total := n;
i := 0;
while i < n do
begin
readln(a);
total := total + i;
total := total - a;
i := i + 1
end;
writeln(total)
end.

@ -0,0 +1,63 @@
program permutations;
var n, lcm, l, i : integer;
var p, loopLength : array [0 .. 100] of integer;
function gcd(a : integer; b : integer): integer;
begin
if a mod b <> 0 then
gcd := gcd(b, a mod b)
else
gcd := b
end;
function loopLengthAt(p : array [0 .. 100] of integer; length : integer; start : integer; current : integer; n : integer; lengths : array [0 .. 100] of integer) : integer;
var isSet, result : integer;
begin
isSet := 0;
if lengths[current] <> 0 then
begin
loopLengthAt := lengths[current];
isSet := 1
end
else if current = start then
if n > 0 then
begin
lengths[current] := n;
loopLengthAt := n;
isSet := 1
end
else skip
else skip;
if isSet = 0 then
begin
result := loopLengthAt(p, length, start, p[current], n + 1, lengths);
lengths[current] := result;
loopLengthAt := result
end
else skip
end;
begin
lcm := 1;
i := 0;
readln(n);
while i < n do
begin
readln(p[i]);
loopLength[i] := 0;
i := i + 1
end;
i := 0;
while i < n do
begin
l := loopLengthAt(p, n, i, i, 0, loopLength);
lcm := lcm * l div gcd(lcm, l);
i := i + 1
end;
writeln(lcm)
end.

@ -0,0 +1,14 @@
{ Parameter passing mechanism from the lab pdf }
PROGRAM parmechanism;
VAR a, b : integer;
PROCEDURE proc(VAR a:integer; b, c : integer);
BEGIN b := b + 2
; a := c*a + b
END;
BEGIN readln(a)
; b := 0
; proc(a,b,2)
; writeln(a,b)
END.

@ -0,0 +1,27 @@
{ This program determines whether a number is prime }
PROGRAM prime;
VAR p,c : integer;
BEGIN
readln(p);
c := 2;
while c * c <= p do
begin
if p mod c <> 0 then
begin
c := c + 1;
if c * c > p then
writeln(1)
else
begin
end
end
else
begin
writeln(0);
c := p + 100 { Exit condition that also works for p = 1 }
end
end
END
.

@ -0,0 +1,34 @@
{ This is some puzzle thing from an old IP exam }
program puzzle;
var len, temp : integer;
var series : array [0 .. 20] of integer;
function canReachLast(i : integer; pos : integer; len : integer; series : array [0 .. 20] of integer) : integer;
begin
if pos < 0 or pos >= len or i >= len then
canReachLast := 0
else if len - 1 = pos + series[pos] or canReachLast(i + 1, pos + series[pos], len, series) = 1 then
canReachLast := 1
else
canReachLast := canReachLast(i + 1, pos - series[pos], len, series)
end;
function isSolvable(len : integer; series : array [0 .. 20] of integer) : integer;
begin
isSolvable := canReachLast(0, 0, len, series)
end;
begin
len := 0;
readln(temp);
series[len] := temp;
while series[len] <> 0 do
begin
len := len + 1;
readln(temp);
series[len] := temp
end;
len := len + 1;
writeln(isSolvable(len, series))
end.

@ -0,0 +1,41 @@
{ Pythagoras program }
PROGRAM pyth;
{
Program that reads three numbers and tells bou
- 0 if they're not a triangle
- 1 if it's a right-angled triangle
- 2 if it's an obtuse triangle
- 3 if it's a sharp triangle
}
VAR a, b, c, t: integer;
BEGIN
readln(a, b, c);
while a > b do
begin
t := a;
a := b;
b := t
end; {a <= b}
while a > c do
begin
t := a;
a := c;
c := t
end; {a <= c && a <= b}
while b > c do
begin
t := b;
b := c;
c := t
end; {a <= b <= c}
if a + b <= c then
writeln(0)
else if a * a + b * b < c * c then
writeln(2)
else if a * a + b * b > c * c then
writeln(3)
else
writeln(1)
END
.

@ -0,0 +1,19 @@
{ Return 42 example from lab pdf }
program return42;
var x : integer;
function return42(n : integer) : integer;
begin
if n > 42 then
return42 := return42(n-1)
else begin
return42 := n;
while return42 < 42 do return42 := return42 + 1
end
end;
begin
readln(x);
writeln(return42(x))
end.

@ -0,0 +1,18 @@
{ This program does a lot of shadowing }
PROGRAM shadowing;
function x (a : integer) : integer;
begin
x := a
end;
function a (b : integer) : integer;
var x : integer;
begin
x := b;
a := x
end;
begin
writeln(a(x(4)))
end.

@ -0,0 +1,23 @@
{ This program does more stuff with subarrays }
program arr;
var arr : array [1 .. 10] of real;
procedure some (rra : array [5 .. 10] of real);
begin
rra[6] := 4
end;
procedure some2 (var rra : array [5 .. 10] of real; var x : real);
begin
rra[6] := 4;
x := 3
end;
begin
arr[3] := 3;
some(arr[2 .. 7]);
writeln(arr[3]);
some2(arr[2 .. 7], arr[4]);
writeln(arr[3], arr[4])
end.
Loading…
Cancel
Save