diff --git a/compiler/CS_CodeGen.jrag b/compiler/CS_CodeGen.jrag index 9c6278a23f55af2e8c06c28f6ef874e5f127b3dd..a02f45533e371c6584df576fd608c8d9d80c6f40 100644 --- a/compiler/CS_CodeGen.jrag +++ b/compiler/CS_CodeGen.jrag @@ -645,6 +645,10 @@ aspect CS_Class { " not declared"); } + public boolean VoidType.CS_needInstance() { + return false; + } + public boolean PrimType.CS_needInstance() { return false; } diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag index 4d4c76b4c7b9f1c754aa5b7119cfe849318ae5f2..228ebd62e8bcfe43703f76ee562a0a67d4b330af 100644 --- a/compiler/C_CodeGen.jrag +++ b/compiler/C_CodeGen.jrag @@ -371,8 +371,10 @@ aspect C_Declarations { env.println("int labcomm"+env.verStr+"_encode_" + env.prefix + getName() + "("); env.indent(); - env.println("struct labcomm"+env.verStr+"_encoder *e,"); - env.println(env.prefix + getName() + " *v"); + env.println("struct labcomm"+env.verStr+"_encoder *e"); + if(!isVoid() ) { + env.println(", "+env.prefix + getName() + " *v"); + } env.unindent(); env.println(");"); @@ -700,8 +702,10 @@ aspect C_Encoder { env = env.nestStruct("(*v)"); env.println("static int encode_" + env.prefix + getName() + "("); env.indent(); - env.println("struct labcomm"+env.verStr+"_writer *w,"); - env.println(env.prefix + getName() + " *v"); + env.println("struct labcomm"+env.verStr+"_writer *w"); + if(!isVoid() ) { + env.println(", "+env.prefix + getName() + " *v"); + } env.unindent(); env.println(")"); env.println("{"); @@ -714,16 +718,19 @@ aspect C_Encoder { // Typesafe encode wrapper env.println("int labcomm"+env.verStr+"_encode_" + env.prefix + getName() + "("); - env.println("struct labcomm"+env.verStr+"_encoder *e,"); - env.println(env.prefix + getName() + " *v"); + env.println("struct labcomm"+env.verStr+"_encoder *e"); + if(!isVoid() ) { + env.println(", "+env.prefix + getName() + " *v"); + } env.unindent(); env.println(")"); env.println("{"); env.indent(); env.println("return labcomm"+env.verStr+"_internal_encode(e, &labcomm"+env.verStr+"_signature_" + env.prefix + getName() + - ", (labcomm"+env.verStr+"_encoder_function)encode_" + env.prefix + getName() + - ", v);"); + ", (labcomm"+env.verStr+"_encoder_function)encode_" + + env.prefix + getName() + + (!isVoid()?", v":", NULL")+");"); env.unindent(); env.println("}"); } @@ -745,7 +752,7 @@ aspect C_Encoder { } public void UserType.C_emitEncoder(C_env env) { - lookupType(getName()).getType().C_emitEncoder(env); + decl().getType().C_emitEncoder(env); } public void StructType.C_emitEncoder(C_env env) { diff --git a/compiler/ErrorCheck.jrag b/compiler/ErrorCheck.jrag index b1e255ecdcbc33685fd91e40f7ee2639b9a80587..caa80815456d4c1a390f2f80f7a5a7e5f74c0b8d 100644 --- a/compiler/ErrorCheck.jrag +++ b/compiler/ErrorCheck.jrag @@ -20,6 +20,7 @@ aspect ErrorCheck { } public void ASTNode.errorCheck(Collection collection) { nameCheck(); + typeCheck(); if(hasErrors()) collection.add(errors); for(int i = 0; i < getNumChild(); i++) { diff --git a/compiler/Java_CodeGen.jrag b/compiler/Java_CodeGen.jrag index 7b7aab4844f754cebdeac65f7ec8a9777b304ac8..96dffe3ff0612806a0f2e1c34739975b6bd53d2a 100644 --- a/compiler/Java_CodeGen.jrag +++ b/compiler/Java_CodeGen.jrag @@ -196,6 +196,7 @@ aspect Java_StructName { aspect Java_Void { syn boolean Decl.isVoid() = getType().isVoid(); + syn boolean UserType.isVoid() = decl().isVoid(); syn boolean Type.isVoid() = false; syn boolean VoidType.isVoid() = true; @@ -746,6 +747,10 @@ aspect Java_Class { " not declared"); } + public boolean VoidType.Java_needInstance() { + return false; + } + public boolean PrimType.Java_needInstance() { return false; } diff --git a/compiler/LabComm.ast b/compiler/LabComm.ast index 7b11255bac395e1b6d0989d1d45f5231c1850a5c..6f290e58d497c19dc4f78ffb443fe6dd3278944a 100644 --- a/compiler/LabComm.ast +++ b/compiler/LabComm.ast @@ -12,7 +12,7 @@ PrimType : Type ::= <Name:String> <Token:int>; UserType : Type ::= <Name:String>; StructType : Type ::= Field*; ParseArrayType : Type ::= Type Dim*; -abstract ArrayType : Type ::= Type Exp*; +abstract ArrayType :Type ::= Type Exp*; VariableArrayType : ArrayType; FixedArrayType : ArrayType; diff --git a/compiler/LabCommParser.parser b/compiler/LabCommParser.parser index 8bef9036102cb7cc6e5c7bd2a9742cc80b225dd9..dea1194a0c06dc7ce19a9813000d9591c4dc40b3 100644 --- a/compiler/LabCommParser.parser +++ b/compiler/LabCommParser.parser @@ -14,7 +14,7 @@ s.append(" *** Syntactic error: unexpected token " + Terminals.NAMES[token.getId()]); throw new SourceError(s.toString()); //super.syntaxError(token); - //throw new RuntimeException(token.getLine(token.getStart()) + ", " + + //throw new RuntimeException(token.getLine(token.getStart()) + ", " + // token.getColumn(token.getStart()) + ": Syntax Error"); } public void scannerError(Scanner.Exception e) { @@ -55,51 +55,50 @@ List var_decl_list = Field var_decl = type.t IDENTIFIER SEMICOLON {: return new Field(t, IDENTIFIER); :} - | type.t IDENTIFIER dim_list.d SEMICOLON + | type.t IDENTIFIER dim_list.d SEMICOLON {: return new Field(new ParseArrayType(t, d), IDENTIFIER); :} ; -TypeDecl type_decl = +TypeDecl type_decl = TYPEDEF type.t IDENTIFIER SEMICOLON {: return new TypeDecl(t, IDENTIFIER); :} - | TYPEDEF type.t IDENTIFIER dim_list.d SEMICOLON + | TYPEDEF type.t IDENTIFIER dim_list.d SEMICOLON {: return new TypeDecl(new ParseArrayType(t, d), IDENTIFIER); :} ; -SampleDecl sample_decl = - SAMPLE type.t IDENTIFIER SEMICOLON +SampleDecl sample_decl = + SAMPLE type.t IDENTIFIER SEMICOLON {: return new SampleDecl(t, IDENTIFIER); :} - | SAMPLE type.t IDENTIFIER dim_list.d SEMICOLON + | SAMPLE type.t IDENTIFIER dim_list.d SEMICOLON {: return new SampleDecl(new ParseArrayType(t, d), IDENTIFIER); :} - | SAMPLE VOID IDENTIFIER SEMICOLON - {: return new SampleDecl(new VoidType(), IDENTIFIER); :} ; Type type = prim_type.p {: return p; :} | user_type.u {: return u; :} | struct_type.s {: return s; :} + | void_type.v {: return v; :} ; -PrimType prim_type = - BOOLEAN +PrimType prim_type = + BOOLEAN {: return new PrimType(BOOLEAN, ASTNode.LABCOMM_BOOLEAN); :} - | BYTE + | BYTE {: return new PrimType(BYTE, ASTNode.LABCOMM_BYTE); :} - | SHORT + | SHORT {: return new PrimType(SHORT, ASTNode.LABCOMM_SHORT); :} - | INT + | INT {: return new PrimType(INT, ASTNode.LABCOMM_INT); :} - | LONG + | LONG {: return new PrimType(LONG, ASTNode.LABCOMM_LONG); :} - | FLOAT + | FLOAT {: return new PrimType(FLOAT, ASTNode.LABCOMM_FLOAT); :} - | DOUBLE + | DOUBLE {: return new PrimType(DOUBLE, ASTNode.LABCOMM_DOUBLE); :} - | STRING + | STRING {: return new PrimType(STRING, ASTNode.LABCOMM_STRING); :} ; -UserType user_type = +UserType user_type = IDENTIFIER {: return new UserType(IDENTIFIER); :} ; @@ -107,6 +106,10 @@ StructType struct_type = STRUCT LBRACE var_decl_list.l RBRACE {: return new StructType(l); :} ; +VoidType void_type = + VOID {: return new VoidType(); :} +; + List dim_list = dim.d {: return new List().add(d); :} | dim_list.l dim.d {: return l.add(d); :} @@ -121,7 +124,7 @@ List exp_list = | exp_list.l COMMA exp.e {: return l.add(e); :} ; -Exp exp = +Exp exp = INTEGER_LITERAL {: return new IntegerLiteral(INTEGER_LITERAL); :} | UNDERSCORE {: return new VariableSize(); :} ; diff --git a/compiler/TypeCheck.jrag b/compiler/TypeCheck.jrag new file mode 100644 index 0000000000000000000000000000000000000000..1536ee8ba223a5582710fef12e9a596d6ddef76b --- /dev/null +++ b/compiler/TypeCheck.jrag @@ -0,0 +1,29 @@ +aspect TypeCheck { + public void ASTNode.typeCheck() { + for (int i = 0; i < getNumChild(); i++) { + getChild(i).typeCheck(); + } + } + + syn boolean Type.isNull(); + eq Type.isNull() = false; + eq VoidType.isNull() = true; + + public void Field.nullTypeCheck() { + if(getType().isNull()) { + error(getName() + ": fields cannot be of type void"); + } + } + + public void ParseArrayType.nullTypeCheck() { + if(getType().isNull()) { + error("array elements cannot be of type void"); + } + } + + public void ArrayType.nullTypeCheck() { + if(getType().isNull()) { + error("array elements cannot be of type void"); + } + } +} diff --git a/examples/simple/Decoder.java b/examples/simple/Decoder.java index 266b895251b6237ee53777dbc05fb8636e13dfff..4ab97e48fccda695f051157b6eb86d293b700d3f 100644 --- a/examples/simple/Decoder.java +++ b/examples/simple/Decoder.java @@ -5,7 +5,7 @@ import java.io.InputStream; import se.lth.control.labcomm.LabCommDecoderChannel; public class Decoder - implements theTwoInts.Handler, anotherTwoInts.Handler, IntString.Handler, TwoArrays.Handler, TwoFixedArrays.Handler + implements theTwoInts.Handler, anotherTwoInts.Handler, IntString.Handler, TwoArrays.Handler, TwoFixedArrays.Handler, doavoid.Handler { @@ -20,6 +20,7 @@ public class Decoder IntString.register(decoder, this); TwoArrays.register(decoder, this); TwoFixedArrays.register(decoder, this); + doavoid.register(decoder, this); try { System.out.println("Running decoder."); @@ -72,6 +73,10 @@ public class Decoder } System.out.println(); } + public void handle_doavoid() throws java.io.IOException { + System.out.println("Got doavoid"); + } + public static void main(String[] arg) throws Exception { diff --git a/examples/simple/simple.lc b/examples/simple/simple.lc index b0fe24abab3369c86a27762f7fbec04591d033e7..c3725ac5b1ed9d68aa83550089f5f5bddf571ac1 100644 --- a/examples/simple/simple.lc +++ b/examples/simple/simple.lc @@ -26,6 +26,6 @@ sample struct { int b[2,3]; } TwoFixedArrays; -// typedef void avoid; +typedef void avoid; -sample void doavoid; +sample avoid doavoid;