Skip to content
Snippets Groups Projects
Commit e1e8fa78 authored by Julien Lopez's avatar Julien Lopez
Browse files

Add more complex RecordType

parent dbf9e961
No related branches found
No related tags found
No related merge requests found
......@@ -45,7 +45,7 @@ public final class QIRRcons extends QIRRecord {
@Override
public final String toString() {
return "{ " + id + ":" + value + "; " + tail + "}";
return "{ " + id + ":" + value + "; " + tail + "}" + (type == null ? "" : " : " + type);
}
@Override
......
......@@ -4,11 +4,14 @@ import com.oracle.truffle.api.source.SourceSection;
import qir.ast.QIRNode;
import qir.driver.IQIRVisitor;
import qir.types.QIRType;
/**
* {@link QIRRecord} is the generic representation of a tuple in QIR.
*/
public abstract class QIRRecord extends QIRNode {
public QIRType type;
public QIRRecord(final SourceSection source) {
super(source);
}
......
......@@ -30,6 +30,8 @@ Coco/R itself) does not fall under the GNU General Public License.
import java.math.BigInteger;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
import com.oracle.truffle.api.frame.FrameDescriptor;
......
......@@ -3,6 +3,8 @@ package qir.parser;
import java.math.BigInteger;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
import com.oracle.truffle.api.frame.FrameDescriptor;
......@@ -271,12 +273,12 @@ public class Parser {
res = result;
break;
}
case 34: {
case 25: {
QIRIf result = Ifexpr();
res = result;
break;
}
case 37: {
case 28: {
QIRRecord result = Tuplecons();
res = result;
break;
......@@ -413,7 +415,7 @@ public class Parser {
Expect(21);
final Token srcToken = t;
Token funName = null;
QIRType type = new FunctionType(Arrays.asList(QIRConstantType.ANY, QIRConstantType.ANY));
QIRType type = new QIRFunctionType(Arrays.asList(QIRConstantType.ANY, QIRConstantType.ANY));
if (la.kind == 22) {
Get();
Expect(1);
......@@ -432,12 +434,12 @@ public class Parser {
QIRIf Ifexpr() {
QIRIf res;
Expect(34);
Expect(25);
final Token srcToken = t;
QIRNode cond = QIR();
Expect(35);
Expect(26);
QIRNode thenNode = QIR();
Expect(36);
Expect(27);
QIRNode elseNode = QIR();
res = new QIRIf(srcFromToken(srcToken), cond, thenNode, elseNode);
return res;
......@@ -445,26 +447,32 @@ public class Parser {
QIRRecord Tuplecons() {
QIRRecord res;
Expect(37);
Expect(28);
res = QIRRnil.getInstance();
final Token srcToken = t;
Token idToken;
Token idToken;
QIRType type = QIRConstantType.ANY;
if (la.kind == 1) {
Get();
idToken = t;
Expect(38);
Expect(29);
QIRNode value = QIR();
res = new QIRRcons(srcFromToken(srcToken), idToken.val, value, res);
while (la.kind == 39) {
while (la.kind == 30) {
Get();
Expect(1);
idToken = t;
Expect(38);
Expect(29);
value = QIR();
res = new QIRRcons(srcFromToken(srcToken), idToken.val, value, res);
}
}
Expect(40);
Expect(31);
if (la.kind == 23) {
Get();
type = RecordType();
}
res.type = type;
return res;
}
......@@ -476,7 +484,7 @@ public class Parser {
if (StartOf(1)) {
QIRNode value = QIR();
res = new QIRLcons(srcFromToken(srcToken), value, res);
while (la.kind == 39) {
while (la.kind == 30) {
Get();
value = QIR();
res = new QIRLcons(srcFromToken(srcToken), value, res);
......@@ -495,7 +503,7 @@ public class Parser {
Expect(45);
Expect(24);
QIRNode ifEmpty = QIR();
Expect(36);
Expect(27);
Expect(24);
QIRNode handler = QIR();
Expect(20);
......@@ -686,16 +694,45 @@ public class Parser {
QIRType Type() {
QIRType res;
QIRType first = ConstantType();
final List<QIRType> types = new ArrayList<>();
types.add(first);
QIRType type;
while (la.kind == 24) {
res = null;
if (StartOf(2)) {
QIRType first = ConstantType();
final List<QIRType> types = new ArrayList<>();
types.add(first);
QIRType type;
while (la.kind == 24) {
Get();
type = ConstantType();
types.add(type);
}
res = types.size() == 1 ? first : new QIRFunctionType(types);
} else if (la.kind == 28) {
res = RecordType();
} else SynErr(63);
return res;
}
QIRRecordType RecordType() {
QIRRecordType res;
Expect(28);
final Map<String, QIRType> types = new HashMap<>();
if (la.kind == 1) {
Get();
type = ConstantType();
types.add(type);
Token idToken = t;
Expect(23);
QIRType type = Type();
types.put(idToken.val, type);
while (la.kind == 30) {
Get();
Expect(1);
idToken = t;
Expect(23);
type = Type();
types.put(idToken.val, type);
}
}
res = types.size() == 1 ? first : new FunctionType(types);
Expect(31);
res = new QIRRecordType(types);
return res;
}
......@@ -703,52 +740,52 @@ public class Parser {
QIRType res;
res = null;
switch (la.kind) {
case 25: {
case 32: {
Get();
res = QIRConstantType.ANY;
break;
}
case 26: {
case 33: {
Get();
res = QIRConstantType.NUMBER;
break;
}
case 27: {
case 34: {
Get();
res = QIRConstantType.BIG_NUMBER;
break;
}
case 28: {
case 35: {
Get();
res = QIRConstantType.DOUBLE;
break;
}
case 29: {
case 36: {
Get();
res = QIRConstantType.BOOLEAN;
break;
}
case 30: {
case 37: {
Get();
res = QIRConstantType.STRING;
break;
}
case 31: {
case 38: {
Get();
res = QIRConstantType.NULL;
break;
}
case 32: {
case 39: {
Get();
res = QIRConstantType.LIST;
break;
}
case 33: {
case 40: {
Get();
res = QIRConstantType.RECORD;
break;
}
default: SynErr(63); break;
default: SynErr(64); break;
}
return res;
}
......@@ -768,7 +805,8 @@ public class Parser {
private static final boolean[][] set = {
{_T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x},
{_x,_T,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_T,_x, _x,_T,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_x, _x,_T,_x,_x, _x,_T,_x,_T, _x,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _x,_x}
{_x,_T,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_T,_T, _x,_x,_T,_x, _x,_T,_x,_x, _x,_T,_x,_x, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_T,_x,_T, _x,_x,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _T,_T,_T,_T, _x,_x},
{_x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _T,_T,_T,_T, _T,_T,_T,_T, _T,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x,_x,_x, _x,_x}
};
......@@ -826,22 +864,22 @@ class Errors {
case 22: s = "\"#\" expected"; break;
case 23: s = "\":\" expected"; break;
case 24: s = "\"->\" expected"; break;
case 25: s = "\"any\" expected"; break;
case 26: s = "\"int\" expected"; break;
case 27: s = "\"big_int\" expected"; break;
case 28: s = "\"double\" expected"; break;
case 29: s = "\"bool\" expected"; break;
case 30: s = "\"string\" expected"; break;
case 31: s = "\"null\" expected"; break;
case 32: s = "\"list\" expected"; break;
case 33: s = "\"record\" expected"; break;
case 34: s = "\"if\" expected"; break;
case 35: s = "\"then\" expected"; break;
case 36: s = "\"else\" expected"; break;
case 37: s = "\"{\" expected"; break;
case 38: s = "\"=\" expected"; break;
case 39: s = "\";\" expected"; break;
case 40: s = "\"}\" expected"; break;
case 25: s = "\"if\" expected"; break;
case 26: s = "\"then\" expected"; break;
case 27: s = "\"else\" expected"; break;
case 28: s = "\"{\" expected"; break;
case 29: s = "\"=\" expected"; break;
case 30: s = "\";\" expected"; break;
case 31: s = "\"}\" expected"; break;
case 32: s = "\"any\" expected"; break;
case 33: s = "\"int\" expected"; break;
case 34: s = "\"big_int\" expected"; break;
case 35: s = "\"double\" expected"; break;
case 36: s = "\"bool\" expected"; break;
case 37: s = "\"string\" expected"; break;
case 38: s = "\"null\" expected"; break;
case 39: s = "\"list\" expected"; break;
case 40: s = "\"record\" expected"; break;
case 41: s = "\"[\" expected"; break;
case 42: s = "\"]\" expected"; break;
case 43: s = "\"match\" expected"; break;
......@@ -864,7 +902,8 @@ class Errors {
case 60: s = "??? expected"; break;
case 61: s = "invalid Expression"; break;
case 62: s = "invalid Boolean"; break;
case 63: s = "invalid ConstantType"; break;
case 63: s = "invalid Type"; break;
case 64: s = "invalid ConstantType"; break;
default: s = "error " + n; break;
}
printMsg(line, col, s);
......
......@@ -314,18 +314,18 @@ public class Scanner {
start.set(66, 102);
start.set(Buffer.EOF, -1);
literals.put("fun", new Integer(21));
literals.put("any", new Integer(25));
literals.put("int", new Integer(26));
literals.put("big_int", new Integer(27));
literals.put("double", new Integer(28));
literals.put("bool", new Integer(29));
literals.put("string", new Integer(30));
literals.put("null", new Integer(31));
literals.put("list", new Integer(32));
literals.put("record", new Integer(33));
literals.put("if", new Integer(34));
literals.put("then", new Integer(35));
literals.put("else", new Integer(36));
literals.put("if", new Integer(25));
literals.put("then", new Integer(26));
literals.put("else", new Integer(27));
literals.put("any", new Integer(32));
literals.put("int", new Integer(33));
literals.put("big_int", new Integer(34));
literals.put("double", new Integer(35));
literals.put("bool", new Integer(36));
literals.put("string", new Integer(37));
literals.put("null", new Integer(38));
literals.put("list", new Integer(39));
literals.put("record", new Integer(40));
literals.put("match", new Integer(43));
literals.put("with", new Integer(44));
literals.put("empty", new Integer(45));
......@@ -549,11 +549,11 @@ public class Scanner {
case 30:
{t.kind = 24; break loop;}
case 31:
{t.kind = 37; break loop;}
{t.kind = 28; break loop;}
case 32:
{t.kind = 39; break loop;}
{t.kind = 30; break loop;}
case 33:
{t.kind = 40; break loop;}
{t.kind = 31; break loop;}
case 34:
{t.kind = 41; break loop;}
case 35:
......@@ -734,9 +734,9 @@ public class Scanner {
else if (ch == '>') {AddCh(); state = 30; break;}
else {t.kind = 11; break loop;}
case 97:
recEnd = pos; recKind = 38;
recEnd = pos; recKind = 29;
if (ch == '=') {AddCh(); state = 17; break;}
else {t.kind = 38; break loop;}
else {t.kind = 29; break loop;}
case 98:
recEnd = pos; recKind = 8;
if (ch == '=') {AddCh(); state = 18; break;}
......
......@@ -153,18 +153,52 @@ identifier (. res = new QIRVariable(srcFromToken(t), t.val); .)
Lambda<out QIRLambda res> =
"fun" (. final Token srcToken = t;
Token funName = null;
QIRType type = new FunctionType(Arrays.asList(QIRConstantType.ANY, QIRConstantType.ANY)); .)
QIRType type = new QIRFunctionType(Arrays.asList(QIRConstantType.ANY, QIRConstantType.ANY)); .)
[ "#" identifier (. funName = t; .)
] [ ":" Type<out type> ] Variable<out QIRVariable var> "->"
QIR<out QIRNode body> (. res = new QIRLambda(srcFromToken(srcToken), funName == null ? null : funName.val, type, var, body, new FrameDescriptor()); .)
.
Type<out QIRType res> =
Ifexpr<out QIRIf res> =
"if" (. final Token srcToken = t; .)
QIR<out QIRNode cond> "then" QIR<out QIRNode thenNode> "else"
QIR<out QIRNode elseNode> (. res = new QIRIf(srcFromToken(srcToken), cond, thenNode, elseNode); .)
.
Tuplecons<out QIRRecord res> =
"{" (. res = QIRRnil.getInstance();
final Token srcToken = t;
Token idToken;
QIRType type = QIRConstantType.ANY; .)
[
identifier (. idToken = t; .)
"=" QIR<out QIRNode value> (. res = new QIRRcons(srcFromToken(srcToken), idToken.val, value, res); .)
{
";" identifier (. idToken = t; .)
"=" QIR<out value> (. res = new QIRRcons(srcFromToken(srcToken), idToken.val, value, res); .)
} ] "}" [ ":" RecordType<out type> ] (. res.type = type; .)
.
Type<out QIRType res> = (. res = null; .)
(
ConstantType<out QIRType first> (. final List<QIRType> types = new ArrayList<>();
types.add(first);
QIRType type; .)
{ "->" ConstantType<out type> (. types.add(type); .)
} (. res = types.size() == 1 ? first : new FunctionType(types); .)
} (. res = types.size() == 1 ? first : new QIRFunctionType(types); .)
| RecordType<out res>
)
.
RecordType<out QIRRecordType res> =
"{" (. final Map<String, QIRType> types = new HashMap<>(); .)
[
identifier (. Token idToken = t; .)
":" Type<out QIRType type> (. types.put(idToken.val, type); .)
{ ";" identifier (. idToken = t; .)
":" Type<out type> (. types.put(idToken.val, type); .)
} ]
"}" (. res = new QIRRecordType(types); .)
.
ConstantType<out QIRType res> = (. res = null; .)
......@@ -181,25 +215,6 @@ ConstantType<out QIRType res> = (. res = null; .)
)
.
Ifexpr<out QIRIf res> =
"if" (. final Token srcToken = t; .)
QIR<out QIRNode cond> "then" QIR<out QIRNode thenNode> "else"
QIR<out QIRNode elseNode> (. res = new QIRIf(srcFromToken(srcToken), cond, thenNode, elseNode); .)
.
Tuplecons<out QIRRecord res> =
"{" (. res = QIRRnil.getInstance();
final Token srcToken = t;
Token idToken; .)
[
identifier (. idToken = t; .)
"=" QIR<out QIRNode value> (. res = new QIRRcons(srcFromToken(srcToken), idToken.val, value, res); .)
{
";" identifier (. idToken = t; .)
"=" QIR<out value> (. res = new QIRRcons(srcFromToken(srcToken), idToken.val, value, res); .)
} ] "}"
.
Listcons<out QIRList res> =
"[" (. res = QIRLnil.getInstance();
final Token srcToken = t; .)
......
(fun : any -> any x -> x) @ [ { x = 2; y = 3 + 4 }; "toto"; (fun : int -> int x -> x + 2) ]
(fun x -> x) @ [ { x = 2; y = 3 + 4 } : { x : int; y : int }; "toto"; (fun : int -> int x -> x + 2) ]
......@@ -4,10 +4,10 @@ import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public final class FunctionType implements QIRType {
public final class QIRFunctionType implements QIRType {
private final List<QIRType> types;
public FunctionType(final List<QIRType> types) {
public QIRFunctionType(final List<QIRType> types) {
this.types = types;
}
......
package qir.types;
import java.util.Map;
import java.util.stream.Collectors;
public class QIRRecordType implements QIRType {
private Map<String, QIRType> types;
public QIRRecordType(final Map<String, QIRType> types) {
this.types = types;
}
@Override
public final String toString() {
return "{ " + types.entrySet().stream().map(e -> e.getKey() + " : " + e.getValue()).collect(Collectors.joining(" -> ")) + " }";
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment