Skip to content

Instantly share code, notes, and snippets.

@cubedtear
Created August 28, 2018 22:08
Show Gist options
  • Select an option

  • Save cubedtear/c08e6b353ac7af7bd9c3e9820f831d3e to your computer and use it in GitHub Desktop.

Select an option

Save cubedtear/c08e6b353ac7af7bd9c3e9820f831d3e to your computer and use it in GitHub Desktop.

Revisions

  1. cubedtear created this gist Aug 28, 2018.
    208 changes: 208 additions & 0 deletions FleetLang.g4
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,208 @@
    grammar FleetLang;

    program
    : tlds+=topLevelDecl* EOF
    ;

    topLevelDecl
    : function
    | typeDecl
    | declaration stmtEnd
    ;

    typeDecl
    : annotations+=annotation* CLASS name=ID '{' (fields+=declaration stmtEnd)* '}'
    ;

    function
    : annotations+=annotation* pub=PUBLIC? (retType=type | voidTy=voidType) name=(ID|FOREIGN_FUNC_ID) '(' (args+=type argNames+=ID (',' args+=type argNames+=ID)* )? ')'
    ( ('{' stmts+=statement* '}') | ';')
    ;

    annotation
    : '@' name=ID ('(' args+=STRING_LIT (',' args+=STRING_LIT)* ')')?
    ;

    type
    : name=ID # customBaseType
    | name=primitiveType # primitiveBaseType
    | '*' ty=type # pointerToType
    | base=type ('[' arrayIdxs+=INT_LIT ']')+ # arrayType
    ;

    primitiveType
    : INT
    | FLOAT
    | DOUBLE
    | BOOLEAN
    | SIZED_INT_TYPE
    ;

    voidType
    : VOID
    ;

    statement
    : IF '(' cond=expression')' whenTrue=statement (ELSE whenFalse=statement)? # ifStmt
    | WHILE '(' cond=expression ')' whenTrue=statement # whileStmt
    | RETURN expr=expression? stmtEnd # returnStmt
    | '{' stmts+=statement* '}' # blockStmt
    | sttc=STATIC? declaration stmtEnd # declStmt
    | assign=assignmentStmt stmtEnd # assignStmt
    | expr=expression stmtEnd # expressionStmt
    | FOR '(' init=declaration ';' cond=expression ';' update=assignmentStmt ')' body=statement # forStmt
    | DO body=statement WHILE '(' cond=expression ')' stmtEnd # doWhileStmt
    | stmtEnd # emptyStmt
    ;

    assignmentStmt
    : left=expression op=assignmentOperator right=expression
    ;

    assignmentOperator
    : op=('+=' | '-=' | '*=' | '/=' | '&&=' | '||=' | '&=' | '|=' | '^=' | '%=' | '=');

    declaration
    : baseType=type name=ID ('=' expr=expression)?
    ;

    expression
    : atom=INT_LIT # intExpr
    | atom=DOUBLE_LIT # doubleExpr
    | atom=FLOAT_LIT # floatExpr
    | atom=STRING_LIT # stringExpr
    | atom=CHAR_LIT # charExpr
    | atom=(TRUE | FALSE) # literalBool
    | '(' ty=type ')' expr=expression # castExpr
    | '{' (arrayIdxs+=INT_LIT (',' arrayIdxs+=INT_LIT)*)? '}' # arrayLiteral
    | atom=ID # idExpr
    | expr=expression '.' member=ID # memberAccess
    | var=expression '[' idx=expression ']' # arrayExpr
    | sign=('+'|'-') expr=expression # signedExpression
    | '!' expr=expression # notExpression
    | SIZEOF '(' type ')' # sizeofExpr
    | func=ID '(' (args+=expression (',' args+=expression)*)? ')' # funcExpr
    | '&' expr=expression # addressExpr
    | '*' expr=expression # dereferenceExpr
    | left=expression op=('&'|'|') right=expression # opExpr
    | left=expression op=('*'|'/'|'%') right=expression # opExpr
    | left=expression op=('+'|'-') right=expression # opExpr
    | left=expression op=('>>'|'<<') right=expression # opExpr
    | '(' expr=expression ')' # parenExpr
    | left=expression op=('=='|'!=') right=expression # comparisonOp
    | left=expression op=('<='|'>='|'>'|'<') right=expression # comparisonOp
    | left=expression op='&&' right=expression # booleanOp
    | left=expression op='||' right=expression # booleanOp
    //| exprs+=expression (',' exprs+=expression)+ # tupleExpr
    | '(' expr=expression ')' # parenBool
    | ASM '(' asmStr=STRING_LIT (
    ':' (outputs+=asmExprPart (',' outputs+=asmExprPart)* )? (
    ':' (inputs+=asmExprPart (',' inputs+=asmExprPart)* )? (
    ':' clobberStr+=STRING_LIT? (',' clobberStr+=STRING_LIT)* )? )? )? ')' #asmExpr
    ;

    asmExprPart
    : str=STRING_LIT '(' var=expression ')'
    ;

    stmtEnd
    : ';'
    ;

    CLASS: 'class';

    INT: 'int';
    FLOAT: 'float';
    DOUBLE: 'double';
    BOOLEAN: 'bool';
    VOID: 'void';

    IF: 'if';
    WHILE: 'while';
    RETURN: 'return';
    ELSE: 'else';
    FOR: 'for';
    DO: 'do';

    TRUE: 'true';
    FALSE: 'false';

    PUBLIC: 'pub';
    STATIC: 'static';

    SIZEOF: 'sizeof';

    ADDRESS: '&'; // And bitwise and

    INCREMENT: '++';
    DECREMENT: '--';

    LEFT_SHIFT: '<<';
    LOGICAL_RIGHT_SHIFT: '>>>';
    ARITHMETIC_RIGHT_SHIFT: '>>';

    LESS_EQUAL: '<=';
    GREATER_EQUAL: '>=';
    LESS_THAN: '<';
    GREATER_THAN: '>';
    EQUALS: '==';
    NOT_EQUALS: '!=';

    ADD_ASSIGN: '+=';
    SUB_ASSIGN: '-=';
    MUL_ASSIGN: '*=';
    DIV_ASSIGN: '/=';
    MODULO_ASSIGN: '%=';
    BOOL_AND_ASSIGN: '&&=';
    BOOL_OR_ASSIGN: '||=';
    BIT_AND_ASSIGN: '&=';
    BIT_OR_ASSIGN: '|=';
    BIT_XOR_ASSIGN: '^=';

    BOOL_OR: '||';
    BOOL_AND: '&&';

    ADD: '+';
    SUBTRACT: '-';
    MULTIPLY: '*';
    DIVIDE: '/';
    BIT_OR: '|';
    BIT_XOR: '^';
    MODULO: '%';

    ASSIGN: '=';


    LPAREN: '(';
    RPAREN: ')';

    AT: '@';

    ASM: 'asm';

    SIZED_INT_TYPE: [iu]('8'|'16'|'32'|'64'|'128');
    ID: [_]?[a-zA-Z][a-zA-Z_0-9]*;
    FOREIGN_FUNC_ID: '#' ID;

    FLOAT_LIT: [0-9]*'.'[0-9]+([eE][+\-]?[0-9]+)?'f';
    DOUBLE_LIT: [0-9]*'.'[0-9]+([eE][+\-]?[0-9]+)?;
    INT_LIT: ('0'[bBxX]?)?[0-9]+([iu]('8'|'16'|'32'|'64'|'128'))?;
    STRING_LIT: '"' StringCharacter* '"';
    CHAR_LIT: '\'' StringCharacter '\'';

    DOT: '.';

    WS: [ \t\r\n]+ -> skip ;

    COMMENT: '/*' .*? '*/' -> channel(HIDDEN);
    LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN);

    fragment Character
    : ~['\\]
    | '\\' [btnfr"'\\]
    ;

    fragment StringCharacter
    : ~["\\]
    | '\\' [btnfr"'\\] // Escape sequence
    ;