25: Add logic for handling float in function calls
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package de.hsrm.compiler.Klang.visitors;
|
package de.hsrm.compiler.Klang.visitors;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -61,9 +62,15 @@ public class GenASM implements Visitor<Void> {
|
|||||||
private int id = -1;
|
private int id = -1;
|
||||||
|
|
||||||
public String getFloat(double d) {
|
public String getFloat(double d) {
|
||||||
String binary = Long.toBinaryString(Double.doubleToLongBits(d));
|
Long longBits = Double.doubleToRawLongBits(d);
|
||||||
String upper = binary.substring(0, 30);
|
String binary = Long.toBinaryString(longBits);
|
||||||
String lower = binary.substring(31, 61);
|
int padCount = 64 - binary.length();
|
||||||
|
while (padCount > 0) {
|
||||||
|
binary = "0" + binary;
|
||||||
|
padCount--;
|
||||||
|
}
|
||||||
|
String upper = binary.substring(0, 32);
|
||||||
|
String lower = binary.substring(32, 64);
|
||||||
long first = Long.parseLong(lower, 2);
|
long first = Long.parseLong(lower, 2);
|
||||||
long second = Long.parseLong(upper, 2);
|
long second = Long.parseLong(upper, 2);
|
||||||
String lbl = ".FL" + ++id;
|
String lbl = ".FL" + ++id;
|
||||||
@@ -101,12 +108,12 @@ public class GenASM implements Visitor<Void> {
|
|||||||
private String mainName;
|
private String mainName;
|
||||||
Map<String, Integer> env = new HashMap<>();
|
Map<String, Integer> env = new HashMap<>();
|
||||||
Set<String> vars;
|
Set<String> vars;
|
||||||
String[] rs = { "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9" };
|
String[] registers = { "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9" };
|
||||||
String[] frs = {"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"};
|
String[] floatRegisters = { "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7" };
|
||||||
private int lCount = 0; // Invariante: lCount ist benutzt
|
private int lCount = 0; // Invariante: lCount ist benutzt
|
||||||
|
|
||||||
private void intToFloat(String src, String dst) {
|
private void intToFloat(String src, String dst) {
|
||||||
this.ex.write(" cvtsi2sd " + src +", " + dst + "\n");
|
this.ex.write(" cvtsi2sd " + src + ", " + dst + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean prepareRegisters(Expression lhs, Expression rhs) {
|
private boolean prepareRegisters(Expression lhs, Expression rhs) {
|
||||||
@@ -131,8 +138,6 @@ public class GenASM implements Visitor<Void> {
|
|||||||
this.ex.write(" popq %rbx\n");
|
this.ex.write(" popq %rbx\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public GenASM(ExWriter ex, String mainName) {
|
public GenASM(ExWriter ex, String mainName) {
|
||||||
this.ex = ex;
|
this.ex = ex;
|
||||||
this.mainName = mainName;
|
this.mainName = mainName;
|
||||||
@@ -183,14 +188,14 @@ public class GenASM implements Visitor<Void> {
|
|||||||
} else {
|
} else {
|
||||||
this.ex.write(" cmp %rax, %rbx\n");
|
this.ex.write(" cmp %rax, %rbx\n");
|
||||||
}
|
}
|
||||||
this.ex.write(" je .L" + lblTrue + "\n");
|
this.ex.write(" je .L" + lblTrue + "\n");
|
||||||
// false
|
// false
|
||||||
this.ex.write(" movq $0, %rax\n");
|
this.ex.write(" movq $0, %rax\n");
|
||||||
this.ex.write(" jmp .L" + lblEnd + "\n");
|
this.ex.write(" jmp .L" + lblEnd + "\n");
|
||||||
this.ex.write(".L" + lblTrue + ":\n");
|
this.ex.write(".L" + lblTrue + ":\n");
|
||||||
// true
|
// true
|
||||||
this.ex.write(" movq $1, %rax\n");
|
this.ex.write(" movq $1, %rax\n");
|
||||||
this.ex.write(".L" + lblEnd + ":\n");
|
this.ex.write(".L" + lblEnd + ":\n");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +248,6 @@ public class GenASM implements Visitor<Void> {
|
|||||||
int lblTrue = ++lCount;
|
int lblTrue = ++lCount;
|
||||||
int lblEnd = ++lCount;
|
int lblEnd = ++lCount;
|
||||||
|
|
||||||
|
|
||||||
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
||||||
if (isFloatOperation) {
|
if (isFloatOperation) {
|
||||||
this.ex.write(" ucomisd %xmm0, %xmm1\n");
|
this.ex.write(" ucomisd %xmm0, %xmm1\n");
|
||||||
@@ -430,20 +434,20 @@ public class GenASM implements Visitor<Void> {
|
|||||||
// also ist das Gesamtergebnis false
|
// also ist das Gesamtergebnis false
|
||||||
e.rhs.welcome(this);
|
e.rhs.welcome(this);
|
||||||
this.ex.write(" cmpq $0, %rax\n");
|
this.ex.write(" cmpq $0, %rax\n");
|
||||||
this.ex.write(" je .L" + lblFalse +"\n");
|
this.ex.write(" je .L" + lblFalse + "\n");
|
||||||
|
|
||||||
// Die Expression wertet zu true aus
|
// Die Expression wertet zu true aus
|
||||||
// Springe am false Teil vorbei
|
// Springe am false Teil vorbei
|
||||||
this.ex.write(".L" + lblTrue +":\n");
|
this.ex.write(".L" + lblTrue + ":\n");
|
||||||
this.ex.write(" movq $1, %rax\n");
|
this.ex.write(" movq $1, %rax\n");
|
||||||
this.ex.write(" jmp .L" + lblEnd + "\n");
|
this.ex.write(" jmp .L" + lblEnd + "\n");
|
||||||
|
|
||||||
// Die Expressoin wertet zu false aus
|
// Die Expressoin wertet zu false aus
|
||||||
this.ex.write(".L" + lblFalse +":\n");
|
this.ex.write(".L" + lblFalse + ":\n");
|
||||||
this.ex.write(" movq $0, %rax\n");
|
this.ex.write(" movq $0, %rax\n");
|
||||||
|
|
||||||
// Das hier ist das ende
|
// Das hier ist das ende
|
||||||
this.ex.write(".L" + lblEnd +":\n");
|
this.ex.write(".L" + lblEnd + ":\n");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,26 +455,26 @@ public class GenASM implements Visitor<Void> {
|
|||||||
public Void visit(NotExpression e) {
|
public Void visit(NotExpression e) {
|
||||||
int lblFalse = ++lCount;
|
int lblFalse = ++lCount;
|
||||||
int lblEnd = ++lCount;
|
int lblEnd = ++lCount;
|
||||||
|
|
||||||
// Werte LHS aus
|
// Werte LHS aus
|
||||||
// Wenn LHS != 0 bedeutet das true, also jumpe zum false Teil
|
// Wenn LHS != 0 bedeutet das true, also jumpe zum false Teil
|
||||||
// Wenn nicht, falle durch zum true Teil
|
// Wenn nicht, falle durch zum true Teil
|
||||||
e.lhs.welcome(this);
|
e.lhs.welcome(this);
|
||||||
this.ex.write(" cmpq $0, %rax\n");
|
this.ex.write(" cmpq $0, %rax\n");
|
||||||
this.ex.write(" jne .L" +lblFalse +"\n");
|
this.ex.write(" jne .L" + lblFalse + "\n");
|
||||||
|
|
||||||
// Hier ist das Ergebnis true
|
// Hier ist das Ergebnis true
|
||||||
// Springe am false Teil vorbei
|
// Springe am false Teil vorbei
|
||||||
this.ex.write(" movq $1, %rax\n");
|
this.ex.write(" movq $1, %rax\n");
|
||||||
this.ex.write(" jmp .L" +lblEnd +"\n");
|
this.ex.write(" jmp .L" + lblEnd + "\n");
|
||||||
|
|
||||||
// Hier ist das Ergebnis false
|
// Hier ist das Ergebnis false
|
||||||
// Falle zum Ende durch
|
// Falle zum Ende durch
|
||||||
this.ex.write(".L" +lblFalse + ":\n");
|
this.ex.write(".L" + lblFalse + ":\n");
|
||||||
this.ex.write("movq $0, %rax\n");
|
this.ex.write("movq $0, %rax\n");
|
||||||
|
|
||||||
// Hier ist das Ende
|
// Hier ist das Ende
|
||||||
this.ex.write(".L" +lblEnd + ":\n");
|
this.ex.write(".L" + lblEnd + ":\n");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,19 +608,51 @@ public class GenASM implements Visitor<Void> {
|
|||||||
this.env = new HashMap<String, Integer>();
|
this.env = new HashMap<String, Integer>();
|
||||||
|
|
||||||
// Merke dir die offsets der parameter, die direkt auf den stack gelegt wurden
|
// Merke dir die offsets der parameter, die direkt auf den stack gelegt wurden
|
||||||
int offset = 16; // Per Stack übergebene Parameter liegen über unserm BSP
|
int offset = 16; // Per Stack übergebene Parameter liegen über unserem BSP
|
||||||
|
int ri = 0;
|
||||||
|
int fi = 0;
|
||||||
// Per stack übergebene variablen in env registrieren
|
// Per stack übergebene variablen in env registrieren
|
||||||
for (int i = this.rs.length; i < e.parameters.length; i++) {
|
var registerParameters = new ArrayList<Parameter>();
|
||||||
env.put(e.parameters[i].name, offset);
|
for (int i = 0; i < e.parameters.length; i++) {
|
||||||
offset += 8;
|
if (e.parameters[i].type.equals(Type.getFloatType())) {
|
||||||
|
if (fi >= this.floatRegisters.length) {
|
||||||
|
// parameter is on stack already
|
||||||
|
env.put(e.parameters[i].name, offset);
|
||||||
|
offset += 8;
|
||||||
|
} else {
|
||||||
|
// parameter is in a xmm register
|
||||||
|
registerParameters.add(e.parameters[i]);
|
||||||
|
fi++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ri >= this.registers.length) {
|
||||||
|
// parameter is on stack already
|
||||||
|
env.put(e.parameters[i].name, offset);
|
||||||
|
offset += 8;
|
||||||
|
} else {
|
||||||
|
// parameter is in a register
|
||||||
|
registerParameters.add(e.parameters[i]);
|
||||||
|
ri++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pushe die aufrufparameter aus den Registern wieder auf den Stack
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
for (int i = 0; i < Math.min(this.rs.length, e.parameters.length); i++) {
|
ri = 0;
|
||||||
this.ex.write(" pushq " + this.rs[i] + "\n");
|
fi = 0;
|
||||||
offset -= 8;
|
for (var param: registerParameters) {
|
||||||
this.env.put(e.parameters[i].name, offset); // negative, liegt unter aktuellem BP
|
if (param.type.equals(Type.getFloatType())) {
|
||||||
|
this.ex.write(" movq "+ this.floatRegisters[fi] + ", %rax\n");
|
||||||
|
this.ex.write(" pushq %rax\n");
|
||||||
|
offset -= 8;
|
||||||
|
this.env.put(param.name, offset); // negative, liegt unter aktuellem BP
|
||||||
|
fi++;
|
||||||
|
} else {
|
||||||
|
this.ex.write(" pushq " + this.registers[ri] + "\n");
|
||||||
|
offset -= 8;
|
||||||
|
this.env.put(param.name, offset); // negative, liegt unter aktuellem BP
|
||||||
|
ri++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserviere Platz auf dem Stack für jede lokale variable
|
// Reserviere Platz auf dem Stack für jede lokale variable
|
||||||
@@ -632,84 +668,80 @@ public class GenASM implements Visitor<Void> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(FunctionCall e) {
|
public Void visit(FunctionCall e) {
|
||||||
/*
|
if (e.arguments.length > 0) {
|
||||||
Idee:
|
// Mapping arguments index -> xmm registers index
|
||||||
Über arguments iterieren, sich für jedes Argument merken an welche Position es kommt
|
int[] xmmIdxs = new int[this.floatRegisters.length];
|
||||||
Über e.arguments iterieren, jedes welcomen, ergebnis auf den stack pushen
|
int fi = -1;
|
||||||
Vom stack in die jeweiligen register / den richtigen Platz auf den Stack pushen
|
|
||||||
*/
|
|
||||||
// // An xmmIdxy[i] steht ein index, der in e.arguments zeigt
|
|
||||||
// // this.frs[i] = register | xmmIdxs[i] = index in arguments das in dieses register gehört
|
|
||||||
// int[] xmmIdxs = new int[this.frs.length];
|
|
||||||
// int fi = 0;
|
|
||||||
// // Selbe Idee wie bei xmmIdxs
|
|
||||||
// int[] rIdxs = new int[this.rs.length];
|
|
||||||
// int ri = 0;
|
|
||||||
//// Selbe Idee wie bei xmmIdxs
|
|
||||||
// ArrayList<Integer> stackIdxs = new ArrayList<Integer>();
|
|
||||||
//
|
|
||||||
// // Go through arguments
|
|
||||||
// // sort them into the memory regions they go when being passed to function later on
|
|
||||||
// for (int i = 0; i < e.arguments.length; i++) {
|
|
||||||
// var arg = e.arguments[i];
|
|
||||||
// if (arg.type.equals(Type.getFloatType())) {
|
|
||||||
// if (fi >= this.frs.length) {
|
|
||||||
// // Float onto stack
|
|
||||||
// stackIdxs.add(i);
|
|
||||||
// } else {
|
|
||||||
// // Float into float reg
|
|
||||||
// xmmIdxs[fi] = i;
|
|
||||||
// fi += 1;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// if (ri >= this.rs.length) {
|
|
||||||
// // bool/int onto stack
|
|
||||||
// stackIdxs.add(i);
|
|
||||||
// } else {
|
|
||||||
// // bool/int into reg
|
|
||||||
// rIdxs[ri] = i;
|
|
||||||
// ri += 1;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Welcome the arguments in order
|
// Mapping arguments index -> all purpose registers index
|
||||||
// for (var arg : e.arguments) {
|
int[] rIdxs = new int[this.registers.length];
|
||||||
// arg.welcome(this);
|
int ri = -1;
|
||||||
// if (arg.type.equals(Type.getFloatType())) {
|
|
||||||
// this.ex.write(" movq %xmm0, %rax\n");
|
// Mapping arguments index -> stack
|
||||||
// this.ex.write(" pushq %rax\n");
|
ArrayList<Integer> stackIdxs = new ArrayList<Integer>();
|
||||||
// } else {
|
|
||||||
// this.ex.write(" pushq %rax\n");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // Move floats from stack to xmm registers
|
|
||||||
// TODO: Check if indexInArguments is valid
|
|
||||||
// for (int i = 0; i < xmmIdxs.length ; i++) {
|
|
||||||
// int indexInArguments = xmmIdxs[i];
|
|
||||||
// int rspOffset = (((e.arguments.length - indexInArguments) - 1) * 8) * -1;
|
|
||||||
// this.ex.write(" movsd " + rspOffset + "(%rsp), " + this.frs[i] + "\n");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Move primitives from stack to all purpose registers
|
// Go through arguments
|
||||||
// TODO: Check if indexInArguments is valid
|
// sort them into the memory regions they go when being passed to functions
|
||||||
// for (int i = 0; i < rIdxs.length ; i++) {
|
for (int i = 0; i < e.arguments.length; i++) {
|
||||||
// int indexInArguments = rIdxs[i];
|
var arg = e.arguments[i];
|
||||||
// int rspOffset = (((e.arguments.length - indexInArguments) - 1) * 8) * -1;
|
if (arg.type.equals(Type.getFloatType())) {
|
||||||
// this.ex.write(" movq " + rspOffset + "(%rsp), " + this.rs[i] + "\n");
|
if (fi < this.floatRegisters.length - 1) {
|
||||||
// }
|
// Float into float reg
|
||||||
// int stackStart = (e.arguments.length - 1) * 8 * -1;
|
fi += 1;
|
||||||
|
xmmIdxs[fi] = i;
|
||||||
|
} else {
|
||||||
|
// Float onto stack
|
||||||
|
stackIdxs.add(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ri < this.registers.length - 1) {
|
||||||
|
// bool/int into reg
|
||||||
|
ri += 1;
|
||||||
|
rIdxs[ri] = i;
|
||||||
|
} else {
|
||||||
|
// bool/int onto stack
|
||||||
|
stackIdxs.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Die ersten sechs params in die register schieben
|
// Welcome the arguments in order, push everything onto the stack
|
||||||
for (int i = 0; i < Math.min(this.rs.length, e.arguments.length); i++) {
|
for (var arg : e.arguments) {
|
||||||
e.arguments[i].welcome(this);
|
arg.welcome(this);
|
||||||
this.ex.write(" movq %rax, " + this.rs[i] + "\n");
|
if (arg.type.equals(Type.getFloatType())) {
|
||||||
}
|
this.ex.write(" movq %xmm0, %rax\n");
|
||||||
|
this.ex.write(" pushq %rax\n");
|
||||||
|
} else {
|
||||||
|
this.ex.write(" pushq %rax\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Den Rest auf den stack pushen
|
// Move floats from stack to xmm registers
|
||||||
for (int i = e.arguments.length - 1; i >= this.rs.length; i--) {
|
for (int i = 0; i <= fi; i++) {
|
||||||
e.arguments[i].welcome(this);
|
int indexInArguments = xmmIdxs[i];
|
||||||
this.ex.write(" pushq %rax\n");
|
int rspOffset = (((e.arguments.length - indexInArguments) - 1) * 8);
|
||||||
|
this.ex.write(" movsd " + rspOffset + "(%rsp), " + this.floatRegisters[i] + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move primitives from stack to all purpose registers
|
||||||
|
for (int i = 0; i <= ri; i++) {
|
||||||
|
int indexInArguments = rIdxs[i];
|
||||||
|
int rspOffset = (((e.arguments.length - indexInArguments) - 1) * 8);
|
||||||
|
this.ex.write(" movq " + rspOffset + "(%rsp), " + this.registers[i] + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move everything else from a higher stack position to our stack frame start
|
||||||
|
int stackStartOffset = ((e.arguments.length) * 8);
|
||||||
|
for (int i = stackIdxs.size() - 1; i >= 0; i--) {
|
||||||
|
stackStartOffset -= 8;
|
||||||
|
int indexInArguments = stackIdxs.get(i);
|
||||||
|
int rspOffset = (((e.arguments.length - indexInArguments) - 1) * 8);
|
||||||
|
this.ex.write(" movq " + rspOffset + "(%rsp), %rax\n");
|
||||||
|
this.ex.write(" movq %rax, " + stackStartOffset + "(%rsp)\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rescue RSP
|
||||||
|
this.ex.write(" addq $" + stackStartOffset + ", %rsp\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ex.write(" call " + e.name + "\n");
|
this.ex.write(" call " + e.name + "\n");
|
||||||
|
|||||||
@@ -12,6 +12,16 @@ int argumentTest(char* name, int expected, int result) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int argumentTest_f(char* name, int expected, int result) {
|
||||||
|
if (expected == result) {
|
||||||
|
succ_f(name, expected, result);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
err_f(name, expected, result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int runFunctionCallTests () {
|
int runFunctionCallTests () {
|
||||||
printf("\nFunction Call Tests \n");
|
printf("\nFunction Call Tests \n");
|
||||||
// Checks that parameters are correctly passed from gcc to functions
|
// Checks that parameters are correctly passed from gcc to functions
|
||||||
@@ -36,4 +46,27 @@ int runFunctionCallTests () {
|
|||||||
argumentTest("get8(...args)", 8, get8());
|
argumentTest("get8(...args)", 8, get8());
|
||||||
argumentTest("get9(...args)", 9, get9());
|
argumentTest("get9(...args)", 9, get9());
|
||||||
argumentTest("get10(...args)", 10, get10());
|
argumentTest("get10(...args)", 10, get10());
|
||||||
|
|
||||||
|
printf("\nFunction Call Tests With Floats \n");
|
||||||
|
argumentTest_f("farg1(...args)", 1.0, farg1(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0));
|
||||||
|
argumentTest_f("farg2(...args)", 2.0, farg2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0));
|
||||||
|
argumentTest_f("farg3(...args)", 3.0, farg3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0));
|
||||||
|
argumentTest_f("farg4(...args)", 4.0, farg4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0));
|
||||||
|
argumentTest_f("farg5(...args)", 5.0, farg5(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0));
|
||||||
|
argumentTest_f("farg6(...args)", 6.0, farg6(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0));
|
||||||
|
argumentTest_f("farg7(...args)", 7.0, farg7(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0));
|
||||||
|
argumentTest_f("farg8(...args)", 8.0, farg8(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0));
|
||||||
|
argumentTest_f("farg9(...args)", 9.0, farg9(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0));
|
||||||
|
argumentTest_f("farg10(...args)", 10.0, farg10(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0));
|
||||||
|
// Checks that parameters are correctly passed from klang to functions
|
||||||
|
argumentTest_f("fget1(...args)", 1.0, fget1());
|
||||||
|
argumentTest_f("fget2(...args)", 2.0, fget2());
|
||||||
|
argumentTest_f("fget3(...args)", 3.0, fget3());
|
||||||
|
argumentTest_f("fget4(...args)", 4.0, fget4());
|
||||||
|
argumentTest_f("fget5(...args)", 5.0, fget5());
|
||||||
|
argumentTest_f("fget6(...args)", 6.0, fget6());
|
||||||
|
argumentTest_f("fget7(...args)", 7.0, fget7());
|
||||||
|
argumentTest_f("fget8(...args)", 8.0, fget8());
|
||||||
|
argumentTest_f("fget9(...args)", 9.0, fget9());
|
||||||
|
argumentTest_f("fget10(...args)", 10.0, fget10());
|
||||||
}
|
}
|
||||||
@@ -18,4 +18,26 @@ int get6();
|
|||||||
int get7();
|
int get7();
|
||||||
int get8();
|
int get8();
|
||||||
int get9();
|
int get9();
|
||||||
int get10();
|
int get10();
|
||||||
|
|
||||||
|
double farg1(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
|
||||||
|
double farg2(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
|
||||||
|
double farg3(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
|
||||||
|
double farg4(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
|
||||||
|
double farg5(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
|
||||||
|
double farg6(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
|
||||||
|
double farg7(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
|
||||||
|
double farg8(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
|
||||||
|
double farg9(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
|
||||||
|
double farg10(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j);
|
||||||
|
|
||||||
|
double fget1();
|
||||||
|
double fget2();
|
||||||
|
double fget3();
|
||||||
|
double fget4();
|
||||||
|
double fget5();
|
||||||
|
double fget6();
|
||||||
|
double fget7();
|
||||||
|
double fget8();
|
||||||
|
double fget9();
|
||||||
|
double fget10();
|
||||||
@@ -28,6 +28,16 @@ void err(char* name, int expected, int result) {
|
|||||||
printf("\033[0;31mERROR:\t\t%s:\tGOT: %d\tExpected: %d\033[0;0m\n", name, result, expected);
|
printf("\033[0;31mERROR:\t\t%s:\tGOT: %d\tExpected: %d\033[0;0m\n", name, result, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void succ_f(char* name, double expected, double result) {
|
||||||
|
incSuccess();
|
||||||
|
printf("\033[0;32mSUCCESS:\t%s:\tGOT: %f\tExpected: %f\033[0;0m\n", name, result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void err_f(char* name, double expected, double result) {
|
||||||
|
incFailure();
|
||||||
|
printf("\033[0;31mERROR:\t\t%s:\tGOT: %f\tExpected: %f\033[0;0m\n", name, result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
void succPrefixOne(char* name, int x, int expected, int result) {
|
void succPrefixOne(char* name, int x, int expected, int result) {
|
||||||
incSuccess();
|
incSuccess();
|
||||||
printf("\033[0;32mSUCCESS:\t%s(%d)\tGOT: %d\tExpected: %d\033[0;0m\n", name, x, result, expected);
|
printf("\033[0;32mSUCCESS:\t%s(%d)\tGOT: %d\tExpected: %d\033[0;0m\n", name, x, result, expected);
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ void incFailure();
|
|||||||
void succ(char* name, int expected, int result);
|
void succ(char* name, int expected, int result);
|
||||||
void err(char* name, int expected, int result);
|
void err(char* name, int expected, int result);
|
||||||
|
|
||||||
|
void succ_f(char* name, double expected, double result);
|
||||||
|
void err_f(char* name, double expected, double result);
|
||||||
|
|
||||||
void succPrefixOne(char* name, int x, int expected, int result);
|
void succPrefixOne(char* name, int x, int expected, int result);
|
||||||
void errPrefixOne(char* name, int x, int expected, int result);
|
void errPrefixOne(char* name, int x, int expected, int result);
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,90 @@ function get10(): int {
|
|||||||
return arg10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
return arg10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FLOATS
|
||||||
|
|
||||||
|
function farg1(a: float, b: float, c: float, d: float, e: float, f: float, g: float, h: float, i: float ,j: float): float {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fget1(): float {
|
||||||
|
return farg1(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function farg2(a: float, b: float, c: float, d: float, e: float, f: float, g: float, h: float, i: float ,j: float): float {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fget2(): float {
|
||||||
|
return farg2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function farg3(a: float, b: float, c: float, d: float, e: float, f: float, g: float, h: float, i: float ,j: float): float {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fget3(): float {
|
||||||
|
return farg3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function farg4(a: float, b: float, c: float, d: float, e: float, f: float, g: float, h: float, i: float ,j: float): float {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fget4(): float {
|
||||||
|
return farg4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function farg5(a: float, b: float, c: float, d: float, e: float, f: float, g: float, h: float, i: float ,j: float): float {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fget5(): float {
|
||||||
|
return farg5(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function farg6(a: float, b: float, c: float, d: float, e: float, f: float, g: float, h: float, i: float ,j: float): float {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fget6(): float {
|
||||||
|
return farg6(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function farg7(a: float, b: float, c: float, d: float, e: float, f: float, g: float, h: float, i: float ,j: float): float {
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fget7(): float {
|
||||||
|
return farg7(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function farg8(a: float, b: float, c: float, d: float, e: float, f: float, g: float, h: float, i: float ,j: float): float {
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fget8(): float {
|
||||||
|
return farg8(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function farg9(a: float, b: float, c: float, d: float, e: float, f: float, g: float, h: float, i: float ,j: float): float {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fget9(): float {
|
||||||
|
return farg9(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function farg10(a: float, b: float, c: float, d: float, e: float, f: float, g: float, h: float, i: float ,j: float): float {
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fget10(): float {
|
||||||
|
return farg10(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// END FLOATS
|
||||||
|
|
||||||
function fac(x: int): int {
|
function fac(x: int): int {
|
||||||
if (x) {
|
if (x) {
|
||||||
return (x * fac((x - 1)));
|
return (x * fac((x - 1)));
|
||||||
|
|||||||
Reference in New Issue
Block a user