mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-08 13:31:03 +00:00
Implemented support for complex casts and parsing complex type names for sizeof(). #121
This commit is contained in:
parent
2ffa6e3ca8
commit
541b92c55b
@ -64,10 +64,16 @@ declType
|
||||
: directive* type directive*
|
||||
;
|
||||
|
||||
typeSpecifier
|
||||
: type #typeSpecifierSimple
|
||||
| typeSpecifier ASTERISK #typeSpecifierPointer
|
||||
| typeSpecifier BRACKET_BEGIN (expr)? BRACKET_END #typeSpecifierArray
|
||||
typeName
|
||||
: type typeNameDeclarator
|
||||
;
|
||||
|
||||
typeNameDeclarator
|
||||
: #typeNameDeclaratorName
|
||||
| typeNameDeclarator PAR_BEGIN parameterListDecl? PAR_END #typeNameDeclaratorProcedure
|
||||
| typeNameDeclarator BRACKET_BEGIN (expr)? BRACKET_END #typeNameDeclaratorArray
|
||||
| ASTERISK directive* typeNameDeclarator #typeNameDeclaratorPointer
|
||||
| PAR_BEGIN typeNameDeclarator PAR_END #typeNameDeclaratorPar
|
||||
;
|
||||
|
||||
declarator
|
||||
@ -125,8 +131,8 @@ parameterListDecl
|
||||
: parameterDecl (COMMA parameterDecl)* ;
|
||||
|
||||
parameterDecl
|
||||
: declType declarator #parameterDeclType
|
||||
| SIMPLETYPE #parameterDeclVoid
|
||||
: declType declarator #parameterDeclTypeDeclarator
|
||||
| typeName #parameterDeclTypeName
|
||||
| PARAM_LIST #parameterDeclList
|
||||
;
|
||||
|
||||
@ -215,11 +221,11 @@ expr
|
||||
| expr DOT NAME #exprDot
|
||||
| expr '->' NAME #exprArrow
|
||||
| expr PAR_BEGIN parameterList? PAR_END #exprCall
|
||||
| SIZEOF PAR_BEGIN ( expr | typeSpecifier ) PAR_END #exprSizeOf
|
||||
| TYPEID PAR_BEGIN ( expr | typeSpecifier ) PAR_END #exprTypeId
|
||||
| SIZEOF PAR_BEGIN ( expr | typeName ) PAR_END #exprSizeOf
|
||||
| TYPEID PAR_BEGIN ( expr | typeName ) PAR_END #exprTypeId
|
||||
| DEFINED PAR_BEGIN? NAME PAR_END? #exprDefined
|
||||
| expr BRACKET_BEGIN commaExpr BRACKET_END #exprArray
|
||||
| PAR_BEGIN typeSpecifier PAR_END expr #exprCast
|
||||
| PAR_BEGIN typeName PAR_END expr #exprCast
|
||||
| ('--' | '++' ) expr #exprPreMod
|
||||
| expr ('--' | '++' ) #exprPostMod
|
||||
| ASTERISK expr #exprPtr
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -138,37 +138,73 @@ public class KickCParserBaseListener implements KickCParserListener {
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterTypeSpecifierSimple(KickCParser.TypeSpecifierSimpleContext ctx) { }
|
||||
@Override public void enterTypeName(KickCParser.TypeNameContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitTypeSpecifierSimple(KickCParser.TypeSpecifierSimpleContext ctx) { }
|
||||
@Override public void exitTypeName(KickCParser.TypeNameContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterTypeSpecifierPointer(KickCParser.TypeSpecifierPointerContext ctx) { }
|
||||
@Override public void enterTypeNameDeclaratorArray(KickCParser.TypeNameDeclaratorArrayContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitTypeSpecifierPointer(KickCParser.TypeSpecifierPointerContext ctx) { }
|
||||
@Override public void exitTypeNameDeclaratorArray(KickCParser.TypeNameDeclaratorArrayContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterTypeSpecifierArray(KickCParser.TypeSpecifierArrayContext ctx) { }
|
||||
@Override public void enterTypeNameDeclaratorPar(KickCParser.TypeNameDeclaratorParContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitTypeSpecifierArray(KickCParser.TypeSpecifierArrayContext ctx) { }
|
||||
@Override public void exitTypeNameDeclaratorPar(KickCParser.TypeNameDeclaratorParContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterTypeNameDeclaratorName(KickCParser.TypeNameDeclaratorNameContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitTypeNameDeclaratorName(KickCParser.TypeNameDeclaratorNameContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterTypeNameDeclaratorProcedure(KickCParser.TypeNameDeclaratorProcedureContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitTypeNameDeclaratorProcedure(KickCParser.TypeNameDeclaratorProcedureContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterTypeNameDeclaratorPointer(KickCParser.TypeNameDeclaratorPointerContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitTypeNameDeclaratorPointer(KickCParser.TypeNameDeclaratorPointerContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@ -426,25 +462,25 @@ public class KickCParserBaseListener implements KickCParserListener {
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterParameterDeclType(KickCParser.ParameterDeclTypeContext ctx) { }
|
||||
@Override public void enterParameterDeclTypeDeclarator(KickCParser.ParameterDeclTypeDeclaratorContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx) { }
|
||||
@Override public void exitParameterDeclTypeDeclarator(KickCParser.ParameterDeclTypeDeclaratorContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx) { }
|
||||
@Override public void enterParameterDeclTypeName(KickCParser.ParameterDeclTypeNameContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx) { }
|
||||
@Override public void exitParameterDeclTypeName(KickCParser.ParameterDeclTypeNameContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -89,21 +89,42 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitTypeSpecifierSimple(KickCParser.TypeSpecifierSimpleContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitTypeName(KickCParser.TypeNameContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitTypeSpecifierPointer(KickCParser.TypeSpecifierPointerContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitTypeNameDeclaratorArray(KickCParser.TypeNameDeclaratorArrayContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitTypeSpecifierArray(KickCParser.TypeSpecifierArrayContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitTypeNameDeclaratorPar(KickCParser.TypeNameDeclaratorParContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitTypeNameDeclaratorName(KickCParser.TypeNameDeclaratorNameContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitTypeNameDeclaratorProcedure(KickCParser.TypeNameDeclaratorProcedureContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitTypeNameDeclaratorPointer(KickCParser.TypeNameDeclaratorPointerContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@ -257,14 +278,14 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitParameterDeclTypeDeclarator(KickCParser.ParameterDeclTypeDeclaratorContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitParameterDeclTypeName(KickCParser.ParameterDeclTypeNameContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -114,41 +114,75 @@ public interface KickCParserListener extends ParseTreeListener {
|
||||
*/
|
||||
void exitDeclType(KickCParser.DeclTypeContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code typeSpecifierSimple}
|
||||
* labeled alternative in {@link KickCParser#typeSpecifier}.
|
||||
* Enter a parse tree produced by {@link KickCParser#typeName}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTypeSpecifierSimple(KickCParser.TypeSpecifierSimpleContext ctx);
|
||||
void enterTypeName(KickCParser.TypeNameContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code typeSpecifierSimple}
|
||||
* labeled alternative in {@link KickCParser#typeSpecifier}.
|
||||
* Exit a parse tree produced by {@link KickCParser#typeName}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTypeSpecifierSimple(KickCParser.TypeSpecifierSimpleContext ctx);
|
||||
void exitTypeName(KickCParser.TypeNameContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code typeSpecifierPointer}
|
||||
* labeled alternative in {@link KickCParser#typeSpecifier}.
|
||||
* Enter a parse tree produced by the {@code typeNameDeclaratorArray}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTypeSpecifierPointer(KickCParser.TypeSpecifierPointerContext ctx);
|
||||
void enterTypeNameDeclaratorArray(KickCParser.TypeNameDeclaratorArrayContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code typeSpecifierPointer}
|
||||
* labeled alternative in {@link KickCParser#typeSpecifier}.
|
||||
* Exit a parse tree produced by the {@code typeNameDeclaratorArray}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTypeSpecifierPointer(KickCParser.TypeSpecifierPointerContext ctx);
|
||||
void exitTypeNameDeclaratorArray(KickCParser.TypeNameDeclaratorArrayContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code typeSpecifierArray}
|
||||
* labeled alternative in {@link KickCParser#typeSpecifier}.
|
||||
* Enter a parse tree produced by the {@code typeNameDeclaratorPar}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTypeSpecifierArray(KickCParser.TypeSpecifierArrayContext ctx);
|
||||
void enterTypeNameDeclaratorPar(KickCParser.TypeNameDeclaratorParContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code typeSpecifierArray}
|
||||
* labeled alternative in {@link KickCParser#typeSpecifier}.
|
||||
* Exit a parse tree produced by the {@code typeNameDeclaratorPar}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTypeSpecifierArray(KickCParser.TypeSpecifierArrayContext ctx);
|
||||
void exitTypeNameDeclaratorPar(KickCParser.TypeNameDeclaratorParContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code typeNameDeclaratorName}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTypeNameDeclaratorName(KickCParser.TypeNameDeclaratorNameContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code typeNameDeclaratorName}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTypeNameDeclaratorName(KickCParser.TypeNameDeclaratorNameContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code typeNameDeclaratorProcedure}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTypeNameDeclaratorProcedure(KickCParser.TypeNameDeclaratorProcedureContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code typeNameDeclaratorProcedure}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTypeNameDeclaratorProcedure(KickCParser.TypeNameDeclaratorProcedureContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code typeNameDeclaratorPointer}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTypeNameDeclaratorPointer(KickCParser.TypeNameDeclaratorPointerContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code typeNameDeclaratorPointer}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTypeNameDeclaratorPointer(KickCParser.TypeNameDeclaratorPointerContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code declaratorPointer}
|
||||
* labeled alternative in {@link KickCParser#declarator}.
|
||||
@ -384,29 +418,29 @@ public interface KickCParserListener extends ParseTreeListener {
|
||||
*/
|
||||
void exitParameterListDecl(KickCParser.ParameterListDeclContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code parameterDeclType}
|
||||
* Enter a parse tree produced by the {@code parameterDeclTypeDeclarator}
|
||||
* labeled alternative in {@link KickCParser#parameterDecl}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterParameterDeclType(KickCParser.ParameterDeclTypeContext ctx);
|
||||
void enterParameterDeclTypeDeclarator(KickCParser.ParameterDeclTypeDeclaratorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code parameterDeclType}
|
||||
* Exit a parse tree produced by the {@code parameterDeclTypeDeclarator}
|
||||
* labeled alternative in {@link KickCParser#parameterDecl}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx);
|
||||
void exitParameterDeclTypeDeclarator(KickCParser.ParameterDeclTypeDeclaratorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code parameterDeclVoid}
|
||||
* Enter a parse tree produced by the {@code parameterDeclTypeName}
|
||||
* labeled alternative in {@link KickCParser#parameterDecl}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx);
|
||||
void enterParameterDeclTypeName(KickCParser.ParameterDeclTypeNameContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code parameterDeclVoid}
|
||||
* Exit a parse tree produced by the {@code parameterDeclTypeName}
|
||||
* labeled alternative in {@link KickCParser#parameterDecl}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx);
|
||||
void exitParameterDeclTypeName(KickCParser.ParameterDeclTypeNameContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code parameterDeclList}
|
||||
* labeled alternative in {@link KickCParser#parameterDecl}.
|
||||
|
@ -75,26 +75,46 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
|
||||
*/
|
||||
T visitDeclType(KickCParser.DeclTypeContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code typeSpecifierSimple}
|
||||
* labeled alternative in {@link KickCParser#typeSpecifier}.
|
||||
* Visit a parse tree produced by {@link KickCParser#typeName}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitTypeSpecifierSimple(KickCParser.TypeSpecifierSimpleContext ctx);
|
||||
T visitTypeName(KickCParser.TypeNameContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code typeSpecifierPointer}
|
||||
* labeled alternative in {@link KickCParser#typeSpecifier}.
|
||||
* Visit a parse tree produced by the {@code typeNameDeclaratorArray}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitTypeSpecifierPointer(KickCParser.TypeSpecifierPointerContext ctx);
|
||||
T visitTypeNameDeclaratorArray(KickCParser.TypeNameDeclaratorArrayContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code typeSpecifierArray}
|
||||
* labeled alternative in {@link KickCParser#typeSpecifier}.
|
||||
* Visit a parse tree produced by the {@code typeNameDeclaratorPar}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitTypeSpecifierArray(KickCParser.TypeSpecifierArrayContext ctx);
|
||||
T visitTypeNameDeclaratorPar(KickCParser.TypeNameDeclaratorParContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code typeNameDeclaratorName}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitTypeNameDeclaratorName(KickCParser.TypeNameDeclaratorNameContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code typeNameDeclaratorProcedure}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitTypeNameDeclaratorProcedure(KickCParser.TypeNameDeclaratorProcedureContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code typeNameDeclaratorPointer}
|
||||
* labeled alternative in {@link KickCParser#typeNameDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitTypeNameDeclaratorPointer(KickCParser.TypeNameDeclaratorPointerContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code declaratorPointer}
|
||||
* labeled alternative in {@link KickCParser#declarator}.
|
||||
@ -234,19 +254,19 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
|
||||
*/
|
||||
T visitParameterListDecl(KickCParser.ParameterListDeclContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code parameterDeclType}
|
||||
* Visit a parse tree produced by the {@code parameterDeclTypeDeclarator}
|
||||
* labeled alternative in {@link KickCParser#parameterDecl}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx);
|
||||
T visitParameterDeclTypeDeclarator(KickCParser.ParameterDeclTypeDeclaratorContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code parameterDeclVoid}
|
||||
* Visit a parse tree produced by the {@code parameterDeclTypeName}
|
||||
* labeled alternative in {@link KickCParser#parameterDecl}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx);
|
||||
T visitParameterDeclTypeName(KickCParser.ParameterDeclTypeNameContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code parameterDeclList}
|
||||
* labeled alternative in {@link KickCParser#parameterDecl}.
|
||||
|
@ -491,6 +491,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
if(SymbolType.VOID.equals(parameter.type))
|
||||
throw new CompileError("Illegal void parameter.", statementSource);
|
||||
|
||||
// Handle parameters without a name in the declaration
|
||||
if(parameter.name==null)
|
||||
throw new CompileError("Illegal unnamed parameter.", statementSource);
|
||||
|
||||
VariableBuilder varBuilder = new VariableBuilder(parameter.name, getCurrentScope(), true, parameter.type, null, currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
|
||||
final Variable paramVar = varBuilder.build();
|
||||
parameterList.add(paramVar);
|
||||
@ -509,7 +513,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx) {
|
||||
public Object visitParameterDeclTypeDeclarator(KickCParser.ParameterDeclTypeDeclaratorContext ctx) {
|
||||
this.visit(ctx.declType());
|
||||
this.visit(ctx.declarator());
|
||||
ParameterDecl paramDecl = new ParameterDecl(varDecl.getVarName(), varDecl.getEffectiveType());
|
||||
@ -518,11 +522,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx) {
|
||||
if(!SymbolType.VOID.getTypeName().equals(ctx.SIMPLETYPE().getText())) {
|
||||
throw new CompileError("Illegal unnamed parameter " + ctx.SIMPLETYPE().getText(), new StatementSource(ctx));
|
||||
}
|
||||
return new ParameterDecl(null, SymbolType.VOID);
|
||||
public Object visitParameterDeclTypeName(KickCParser.ParameterDeclTypeNameContext ctx) {
|
||||
SymbolType paramType = (SymbolType) this.visit(ctx.typeName());
|
||||
return new ParameterDecl(null, paramType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1945,6 +1947,16 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitTypeName(KickCParser.TypeNameContext ctx) {
|
||||
varDeclPush();
|
||||
this.visit(ctx.type());
|
||||
this.visit(ctx.typeNameDeclarator());
|
||||
final SymbolType type = varDecl.getEffectiveType();
|
||||
varDeclPop();
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDeclaratorPointer(KickCParser.DeclaratorPointerContext ctx) {
|
||||
final SymbolType elementDeclType = varDecl.getEffectiveType();
|
||||
@ -1955,6 +1967,16 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitTypeNameDeclaratorPointer(KickCParser.TypeNameDeclaratorPointerContext ctx) {
|
||||
final SymbolType elementDeclType = varDecl.getEffectiveType();
|
||||
SymbolTypePointer pointerType = new SymbolTypePointer(elementDeclType);
|
||||
final List<Directive> typeDirectives = getDirectives(ctx.directive());
|
||||
varDecl.setVarDeclTypeAndDirectives(pointerType, typeDirectives);
|
||||
this.visit(ctx.typeNameDeclarator());
|
||||
return varDecl.getEffectiveType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDeclaratorArray(KickCParser.DeclaratorArrayContext ctx) {
|
||||
this.visit(ctx.declarator());
|
||||
@ -1976,18 +1998,50 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitTypeNameDeclaratorArray(KickCParser.TypeNameDeclaratorArrayContext ctx) {
|
||||
this.visit(ctx.typeNameDeclarator());
|
||||
// Handle array type declaration by updating the declared type and the array spec
|
||||
ArraySpec arraySpec;
|
||||
if(ctx.expr() != null) {
|
||||
varDeclPush();
|
||||
RValue sizeVal = (RValue) visit(ctx.expr());
|
||||
if(!(sizeVal instanceof ConstantValue))
|
||||
throw new CompileError(sizeVal.toString() + " is not constant or is not defined", new StatementSource(ctx));
|
||||
varDeclPop();
|
||||
arraySpec = new ArraySpec((ConstantValue) sizeVal);
|
||||
} else {
|
||||
arraySpec = new ArraySpec();
|
||||
}
|
||||
final SymbolType elementDeclType = varDecl.getEffectiveType();
|
||||
SymbolType arrayDeclType = new SymbolTypePointer(elementDeclType, arraySpec, false, false);
|
||||
varDecl.setVarDeclType(arrayDeclType);
|
||||
return varDecl.getEffectiveType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDeclaratorPar(KickCParser.DeclaratorParContext ctx) {
|
||||
this.visit(ctx.declarator());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitTypeNameDeclaratorPar(KickCParser.TypeNameDeclaratorParContext ctx) {
|
||||
this.visit(ctx.typeNameDeclarator());
|
||||
return varDecl.getEffectiveType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDeclaratorName(KickCParser.DeclaratorNameContext ctx) {
|
||||
varDecl.setVarName(ctx.getText());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitTypeNameDeclaratorName(KickCParser.TypeNameDeclaratorNameContext ctx) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDeclaratorProcedure(KickCParser.DeclaratorProcedureContext ctx) {
|
||||
List<ParameterDecl> parameters = new ArrayList<>();
|
||||
@ -2012,6 +2066,30 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitTypeNameDeclaratorProcedure(KickCParser.TypeNameDeclaratorProcedureContext ctx) {
|
||||
List<ParameterDecl> parameters = new ArrayList<>();
|
||||
List<SymbolType> paramTypes = new ArrayList<>();
|
||||
if(ctx.parameterListDecl() != null)
|
||||
for(KickCParser.ParameterDeclContext parameterDeclContext : ctx.parameterListDecl().parameterDecl()) {
|
||||
varDeclPush();
|
||||
ParameterDecl paramDecl = (ParameterDecl) this.visit(parameterDeclContext);
|
||||
// Handle parameter list with "VOID"
|
||||
if(SymbolType.VOID.equals(paramDecl.type) && ctx.parameterListDecl().parameterDecl().size()==1)
|
||||
; // Ignore the void parameter
|
||||
else {
|
||||
paramTypes.add(paramDecl.type);
|
||||
parameters.add(paramDecl);
|
||||
}
|
||||
varDeclPop();
|
||||
}
|
||||
SymbolType returnType = varDecl.getEffectiveType();
|
||||
varDecl.setVarDeclType(new SymbolTypeProcedure(returnType, paramTypes));
|
||||
varDecl.setParameters(parameters);
|
||||
visit(ctx.typeNameDeclarator());
|
||||
return varDecl.getEffectiveType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitTypeNamedRef(KickCParser.TypeNamedRefContext ctx) {
|
||||
Scope typeDefScope = program.getScope().getTypeDefScope();
|
||||
@ -2206,32 +2284,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
return structMemberRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SymbolType visitTypeSpecifierSimple(KickCParser.TypeSpecifierSimpleContext ctx) {
|
||||
varDeclPush();
|
||||
this.visit(ctx.type());
|
||||
final SymbolType type = varDecl.getEffectiveType();
|
||||
varDeclPop();
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SymbolType visitTypeSpecifierPointer(KickCParser.TypeSpecifierPointerContext ctx) {
|
||||
return new SymbolTypePointer((SymbolType) this.visit(ctx.typeSpecifier()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SymbolType visitTypeSpecifierArray(KickCParser.TypeSpecifierArrayContext ctx) {
|
||||
SymbolType elementType = (SymbolType) visit(ctx.typeSpecifier());
|
||||
if(ctx.expr() != null)
|
||||
throw new InternalError("Not implemented!");
|
||||
return new SymbolTypePointer(elementType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue visitExprCast(KickCParser.ExprCastContext ctx) {
|
||||
RValue child = (RValue) this.visit(ctx.expr());
|
||||
SymbolType castType = (SymbolType) this.visit(ctx.typeSpecifier());
|
||||
SymbolType castType = (SymbolType) this.visit(ctx.typeName());
|
||||
Operator operator = Operators.getCastUnary(castType);
|
||||
if(child instanceof ConstantValue) {
|
||||
consumeExpr(child);
|
||||
@ -2243,9 +2299,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
@Override
|
||||
public Object visitExprSizeOf(KickCParser.ExprSizeOfContext ctx) {
|
||||
if(ctx.typeSpecifier() != null) {
|
||||
if(ctx.typeName() != null) {
|
||||
// sizeof(type) - add directly
|
||||
SymbolType type = (SymbolType) this.visit(ctx.typeSpecifier());
|
||||
SymbolType type = (SymbolType) this.visit(ctx.typeName());
|
||||
return SizeOfConstants.getSizeOfConstantVar(program.getScope(), type);
|
||||
} else {
|
||||
// sizeof(expression) - add a unary expression to be resolved later
|
||||
@ -2261,9 +2317,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
@Override
|
||||
public Object visitExprTypeId(KickCParser.ExprTypeIdContext ctx) {
|
||||
if(ctx.typeSpecifier() != null) {
|
||||
if(ctx.typeName() != null) {
|
||||
// typeid(type) - add directly
|
||||
SymbolType type = (SymbolType) this.visit(ctx.typeSpecifier());
|
||||
SymbolType type = (SymbolType) this.visit(ctx.typeName());
|
||||
return OperatorTypeId.getTypeIdConstantVar(program.getScope(), type);
|
||||
} else {
|
||||
// typeid(expression) - add a unary expression to be resolved later
|
||||
|
@ -273,7 +273,7 @@ public class TestPreprocessor {
|
||||
@Override
|
||||
public Object visitExprCast(KickCParser.ExprCastContext ctx) {
|
||||
out.append("cast(");
|
||||
out.append(ctx.typeSpecifier().getText());
|
||||
out.append(ctx.typeName().getText());
|
||||
out.append(",");
|
||||
this.visit(ctx.expr());
|
||||
out.append(")");
|
||||
|
@ -9,6 +9,11 @@ import java.io.IOException;
|
||||
*/
|
||||
public class TestProgramsFast extends TestPrograms {
|
||||
|
||||
@Test
|
||||
public void testProcedureDeclare11() throws IOException {
|
||||
compileAndCompare("procedure-declare-11.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcedureDeclare10() throws IOException {
|
||||
compileAndCompare("procedure-declare-10.c");
|
||||
|
14
src/test/kc/procedure-declare-11.c
Normal file
14
src/test/kc/procedure-declare-11.c
Normal file
@ -0,0 +1,14 @@
|
||||
// Pointer to pointer to procedure without typedef (uses a very complex cast)
|
||||
|
||||
// Define const pointer to pointer to no-arg-noreturn procedure
|
||||
void (** const IRQ)(void) = (void(**)(void))0x314;
|
||||
|
||||
char * const SCREEN = (char*)0x0400;
|
||||
|
||||
__interrupt void irq() {
|
||||
SCREEN[0]++;
|
||||
}
|
||||
|
||||
void main() {
|
||||
*IRQ = &irq;
|
||||
}
|
28
src/test/ref/procedure-declare-11.asm
Normal file
28
src/test/ref/procedure-declare-11.asm
Normal file
@ -0,0 +1,28 @@
|
||||
// Pointer to pointer to procedure without typedef (uses a very complex cast)
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="procedure-declare-11.prg", type="prg", segments="Program"]
|
||||
.segmentdef Program [segments="Basic, Code, Data"]
|
||||
.segmentdef Basic [start=$0801]
|
||||
.segmentdef Code [start=$80d]
|
||||
.segmentdef Data [startAfter="Code"]
|
||||
.segment Basic
|
||||
:BasicUpstart(main)
|
||||
// Define const pointer to pointer to no-arg-noreturn procedure
|
||||
.label IRQ = $314
|
||||
.label SCREEN = $400
|
||||
.segment Code
|
||||
main: {
|
||||
// *IRQ = &irq
|
||||
lda #<irq
|
||||
sta IRQ
|
||||
lda #>irq
|
||||
sta IRQ+1
|
||||
// }
|
||||
rts
|
||||
}
|
||||
irq: {
|
||||
// SCREEN[0]++;
|
||||
inc SCREEN
|
||||
// }
|
||||
jmp $ea81
|
||||
}
|
16
src/test/ref/procedure-declare-11.cfg
Normal file
16
src/test/ref/procedure-declare-11.cfg
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
[0] *IRQ = &irq
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[1] return
|
||||
to:@return
|
||||
|
||||
__interrupt(rom_min_c64) void irq()
|
||||
irq: scope:[irq] from
|
||||
[2] *SCREEN = ++ *SCREEN
|
||||
to:irq::@return
|
||||
irq::@return: scope:[irq] from irq
|
||||
[3] return
|
||||
to:@return
|
203
src/test/ref/procedure-declare-11.log
Normal file
203
src/test/ref/procedure-declare-11.log
Normal file
@ -0,0 +1,203 @@
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
|
||||
__interrupt(rom_min_c64) void irq()
|
||||
irq: scope:[irq] from
|
||||
SCREEN[0] = ++ SCREEN[0]
|
||||
to:irq::@return
|
||||
irq::@return: scope:[irq] from irq
|
||||
return
|
||||
to:@return
|
||||
|
||||
void main()
|
||||
main: scope:[main] from __start
|
||||
*IRQ = &irq
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
to:__start::@1
|
||||
__start::@1: scope:[__start] from __start
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start::@1
|
||||
return
|
||||
to:@return
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
constant void()** const IRQ = (void()**)$314
|
||||
constant byte* const SCREEN = (byte*)$400
|
||||
void __start()
|
||||
__interrupt(rom_min_c64) void irq()
|
||||
void main()
|
||||
|
||||
Adding number conversion cast (unumber) 0 in SCREEN[0] = ++ SCREEN[0]
|
||||
Adding number conversion cast (unumber) 0 in SCREEN[0] = ++ SCREEN[(unumber)0]
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Simplifying constant pointer cast (void()**) 788
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Simplifying constant integer cast 0
|
||||
Simplifying constant integer cast 0
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 0
|
||||
Finalized unsigned number type (byte) 0
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Simplifying expression containing zero SCREEN in [0] SCREEN[0] = ++ SCREEN[0]
|
||||
Simplifying expression containing zero SCREEN in [0] SCREEN[0] = ++ *SCREEN
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Removing unused procedure __start
|
||||
Removing unused procedure block __start
|
||||
Removing unused procedure block __start::@1
|
||||
Removing unused procedure block __start::@return
|
||||
Successful SSA optimization PassNEliminateEmptyStart
|
||||
CALL GRAPH
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
[0] *IRQ = &irq
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[1] return
|
||||
to:@return
|
||||
|
||||
__interrupt(rom_min_c64) void irq()
|
||||
irq: scope:[irq] from
|
||||
[2] *SCREEN = ++ *SCREEN
|
||||
to:irq::@return
|
||||
irq::@return: scope:[irq] from irq
|
||||
[3] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
__interrupt(rom_min_c64) void irq()
|
||||
void main()
|
||||
|
||||
Initial phi equivalence classes
|
||||
Complete equivalence classes
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [0] *IRQ = &irq [ ] ( [ ] { } ) always clobbers reg byte a
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [irq]
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [irq] best 60 combination
|
||||
Uplifting [main] best 60 combination
|
||||
Uplifting [] best 60 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
// Pointer to pointer to procedure without typedef (uses a very complex cast)
|
||||
// Upstart
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="procedure-declare-11.prg", type="prg", segments="Program"]
|
||||
.segmentdef Program [segments="Basic, Code, Data"]
|
||||
.segmentdef Basic [start=$0801]
|
||||
.segmentdef Code [start=$80d]
|
||||
.segmentdef Data [startAfter="Code"]
|
||||
.segment Basic
|
||||
:BasicUpstart(main)
|
||||
// Global Constants & labels
|
||||
// Define const pointer to pointer to no-arg-noreturn procedure
|
||||
.label IRQ = $314
|
||||
.label SCREEN = $400
|
||||
.segment Code
|
||||
// main
|
||||
main: {
|
||||
// [0] *IRQ = &irq -- _deref_qprc1=pprc2
|
||||
lda #<irq
|
||||
sta IRQ
|
||||
lda #>irq
|
||||
sta IRQ+1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [1] return
|
||||
rts
|
||||
}
|
||||
// irq
|
||||
irq: {
|
||||
// interrupt(isr_rom_min_c64_entry) -- isr_rom_min_c64_entry
|
||||
// [2] *SCREEN = ++ *SCREEN -- _deref_pbuc1=_inc__deref_pbuc1
|
||||
inc SCREEN
|
||||
jmp __breturn
|
||||
// irq::@return
|
||||
__breturn:
|
||||
// [3] return
|
||||
// interrupt(isr_rom_min_c64_exit) -- isr_rom_min_c64_exit
|
||||
jmp $ea81
|
||||
}
|
||||
// File Data
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp __breturn
|
||||
Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction __breturn:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
constant void()** const IRQ = (void()**) 788
|
||||
constant byte* const SCREEN = (byte*) 1024
|
||||
__interrupt(rom_min_c64) void irq()
|
||||
void main()
|
||||
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 54
|
||||
|
||||
// File Comments
|
||||
// Pointer to pointer to procedure without typedef (uses a very complex cast)
|
||||
// Upstart
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="procedure-declare-11.prg", type="prg", segments="Program"]
|
||||
.segmentdef Program [segments="Basic, Code, Data"]
|
||||
.segmentdef Basic [start=$0801]
|
||||
.segmentdef Code [start=$80d]
|
||||
.segmentdef Data [startAfter="Code"]
|
||||
.segment Basic
|
||||
:BasicUpstart(main)
|
||||
// Global Constants & labels
|
||||
// Define const pointer to pointer to no-arg-noreturn procedure
|
||||
.label IRQ = $314
|
||||
.label SCREEN = $400
|
||||
.segment Code
|
||||
// main
|
||||
main: {
|
||||
// *IRQ = &irq
|
||||
// [0] *IRQ = &irq -- _deref_qprc1=pprc2
|
||||
lda #<irq
|
||||
sta IRQ
|
||||
lda #>irq
|
||||
sta IRQ+1
|
||||
// main::@return
|
||||
// }
|
||||
// [1] return
|
||||
rts
|
||||
}
|
||||
// irq
|
||||
irq: {
|
||||
// interrupt(isr_rom_min_c64_entry) -- isr_rom_min_c64_entry
|
||||
// SCREEN[0]++;
|
||||
// [2] *SCREEN = ++ *SCREEN -- _deref_pbuc1=_inc__deref_pbuc1
|
||||
inc SCREEN
|
||||
// irq::@return
|
||||
// }
|
||||
// [3] return
|
||||
// interrupt(isr_rom_min_c64_exit) -- isr_rom_min_c64_exit
|
||||
jmp $ea81
|
||||
}
|
||||
// File Data
|
||||
|
5
src/test/ref/procedure-declare-11.sym
Normal file
5
src/test/ref/procedure-declare-11.sym
Normal file
@ -0,0 +1,5 @@
|
||||
constant void()** const IRQ = (void()**) 788
|
||||
constant byte* const SCREEN = (byte*) 1024
|
||||
__interrupt(rom_min_c64) void irq()
|
||||
void main()
|
||||
|
Loading…
Reference in New Issue
Block a user