From b25d312c0f06de310ae8420ae6a0e84330724255 Mon Sep 17 00:00:00 2001 From: Sven Gestegard Robertz <sven.robertz@cs.lth.se> Date: Fri, 21 Mar 2014 18:12:56 +0100 Subject: [PATCH] added type check for void types --- compiler/CS_CodeGen.jrag | 4 ++++ compiler/C_CodeGen.jrag | 25 ++++++++++++-------- compiler/ErrorCheck.jrag | 1 + compiler/Java_CodeGen.jrag | 5 ++++ compiler/LabComm.ast | 2 +- compiler/LabCommParser.parser | 43 +++++++++++++++++++---------------- compiler/TypeCheck.jrag | 29 +++++++++++++++++++++++ examples/simple/Decoder.java | 7 +++++- examples/simple/simple.lc | 4 ++-- 9 files changed, 87 insertions(+), 33 deletions(-) create mode 100644 compiler/TypeCheck.jrag diff --git a/compiler/CS_CodeGen.jrag b/compiler/CS_CodeGen.jrag index 9c6278a..a02f455 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 4d4c76b..228ebd6 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 b1e255e..caa8081 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 7b7aab4..96dffe3 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 7b11255..6f290e5 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 8bef903..dea1194 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 0000000..1536ee8 --- /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 266b895..4ab97e4 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 b0fe24a..c3725ac 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; -- GitLab