wraith-lang/generators/wraith.y

401 lines
13 KiB
Plaintext

%code requires {
#include "../src/ast.h"
}
%{
#include <stdio.h>
#include "../src/ast.h"
void yyerror(FILE *fp, Node **pRootNode, char *s)
{
fprintf (stderr, "%s\n", s);
}
extern char *yytext;
extern int yylex (void);
extern FILE *yyin;
%}
%define api.value.type {struct Node*}
%token VOID
%token INT
%token UINT
%token FLOAT
%token DOUBLE
%token STRING
%token BOOL
%token STRUCT
%token INTERFACE
%token RETURN
%token STATIC
%token REFERENCE
%token ALLOC
%token IF
%token ELSE
%token IN
%token FOR
%token NUMBER
%token ID
%token STRING_LITERAL
%token PLUS
%token MINUS
%token STAR
%token SLASH
%token PERCENT
%token EQUAL
%token LESS_THAN
%token GREATER_THAN
%token QUOTE
%token BANG
%token BAR
%token AMPERSAND
%token POINT
%token COMMA
%token SEMICOLON
%token COLON
%token QUESTION
%token LEFT_PAREN
%token RIGHT_PAREN
%token LEFT_BRACE
%token RIGHT_BRACE
%token LEFT_BRACKET
%token RIGHT_BRACKET
%token COMMENT
%token NEWLINE
%parse-param { FILE* fp } { Node **pRootNode }
%define parse.error verbose
%left GREATER_THAN LESS_THAN EQUAL
%left PLUS MINUS
%left STAR PERCENT
%left BANG BAR
%left LEFT_PAREN RIGHT_PAREN
%%
Program : TopLevelDeclarations
{
*pRootNode = $1;
}
BaseType : VOID
{
$$ = MakePrimitiveTypeNode(Void);
}
| INT
{
$$ = MakePrimitiveTypeNode(Int);
}
| UINT
{
$$ = MakePrimitiveTypeNode(UInt);
}
| FLOAT
{
$$ = MakePrimitiveTypeNode(Float);
}
| DOUBLE
{
$$ = MakePrimitiveTypeNode(Double);
}
| STRING
{
$$ = MakePrimitiveTypeNode(String);
}
| BOOL
{
$$ = MakePrimitiveTypeNode(Bool);
}
| Identifier
{
$$ = MakeCustomTypeNode(yytext);
}
| REFERENCE LESS_THAN Type GREATER_THAN
{
$$ = MakeReferenceTypeNode($3);
}
;
Type : BaseType
{
$$ = MakeTypeNode($1);
}
Identifier : ID
{
$$ = MakeIdentifierNode(yytext);
}
HeapAllocation : ALLOC Type
{
$$ = MakeAllocNode($2);
}
AccessExpression : Identifier POINT AccessExpression
{
$$ = MakeAccessExpressionNode($1, $3);
}
| Identifier
{
$$ = $1;
}
Number : NUMBER
{
$$ = MakeNumberNode(yytext);
}
PrimaryExpression : Number
| STRING_LITERAL
{
$$ = MakeStringNode(yytext);
}
| LEFT_PAREN Expression RIGHT_PAREN
{
$$ = $2;
}
| FunctionCallExpression
| AccessExpression
;
UnaryExpression : BANG Expression
{
$$ = MakeUnaryNode(Negate, $2);
}
BinaryExpression : Expression PLUS Expression
{
$$ = MakeBinaryNode(Add, $1, $3);
}
| Expression MINUS Expression
{
$$ = MakeBinaryNode(Subtract, $1, $3);
}
| Expression STAR Expression
{
$$ = MakeBinaryNode(Multiply, $1, $3);
}
| Expression PERCENT Expression
{
$$ = MakeBinaryNode(Mod, $1, $3);
}
| Expression LESS_THAN Expression
{
$$ = MakeBinaryNode(LessThan, $1, $3);
}
| Expression GREATER_THAN Expression
{
$$ = MakeBinaryNode(GreaterThan, $1, $3);
}
| Expression EQUAL EQUAL Expression
{
$$ = MakeBinaryNode(Equal, $1, $4);
}
| Expression BAR BAR Expression
{
$$ = MakeBinaryNode(LogicalOr, $1, $4);
}
Expression : BinaryExpression
| UnaryExpression
| PrimaryExpression
| HeapAllocation
;
VariableDeclaration : Identifier COLON Type
{
$$ = MakeDeclarationNode($3, $1);
}
AssignmentStatement : VariableDeclaration EQUAL Expression
{
$$ = MakeAssignmentNode($1, $3);
}
| AccessExpression EQUAL Expression
{
$$ = MakeAssignmentNode($1, $3);
}
| Identifier EQUAL Expression
{
$$ = MakeAssignmentNode($1, $3);
}
ReturnStatement : RETURN Expression
{
$$ = MakeReturnStatementNode($2);
}
| RETURN
{
$$ = MakeReturnVoidStatementNode();
}
FunctionCallExpression : AccessExpression LEFT_PAREN Arguments RIGHT_PAREN
{
$$ = MakeFunctionCallExpressionNode($1, $3);
}
PartialStatement : FunctionCallExpression
| AssignmentStatement
| VariableDeclaration
| ReturnStatement
;
IfStatement : IF LEFT_PAREN Expression RIGHT_PAREN LEFT_BRACE Statements RIGHT_BRACE
{
$$ = MakeIfNode($3, $6);
}
Conditional : IfStatement
| IfStatement ELSE LEFT_BRACE Statements RIGHT_BRACE
{
$$ = MakeIfElseNode($1, $4);
}
| IfStatement ELSE Conditional
{
$$ = MakeIfElseNode($1, $3);
}
ForStatement : FOR LEFT_PAREN VariableDeclaration IN LEFT_BRACKET Number POINT POINT Number RIGHT_BRACKET RIGHT_PAREN LEFT_BRACE Statements RIGHT_BRACE
{
$$ = MakeForLoopNode($3, $6, $9, $13);
}
Statement : PartialStatement SEMICOLON
| Conditional
| ForStatement
;
Statements : Statement
{
$$ = StartStatementSequenceNode($1);
}
| Statements Statement
{
$$ = AddStatement($1, $2);
}
Arguments : PrimaryExpression
{
$$ = StartFunctionArgumentSequenceNode($1);
}
| Arguments COMMA PrimaryExpression
{
$$ = AddFunctionArgumentNode($1, $3);
}
|
{
$$ = MakeEmptyFunctionArgumentSequenceNode();
}
SignatureArguments : VariableDeclaration
{
$$ = StartFunctionSignatureArgumentsNode($1);
}
| SignatureArguments COMMA VariableDeclaration
{
$$ = AddFunctionSignatureArgumentNode($1, $3);
}
|
{
$$ = MakeEmptyFunctionSignatureArgumentsNode();
}
;
Body : LEFT_BRACE Statements RIGHT_BRACE
{
$$ = $2;
}
GenericConstraint : Identifier COLON Identifier
{
$$ = MakeGenericConstraintNode($1, $3);
}
GenericConstraints : GenericConstraint
{
$$ = StartGenericConstraintsNode($1);
}
| GenericConstraints COMMA GenericConstraint
{
$$ = AddGenericConstraint($1, $3);
}
;
GenericConstraintClause : LESS_THAN GenericConstraints GREATER_THAN
{
$$ = $2;
}
|
{
$$ = MakeEmptyGenericConstraintsNode();
}
;
/* FIXME: modifiers should be recursive */
FunctionSignature : Identifier GenericConstraintClause LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type
{
$$ = MakeFunctionSignatureNode($1, $7, $4, MakeFunctionModifiersNode(NULL, 0), $2);
}
| STATIC Identifier LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type
{
Node *modifier = MakeStaticNode();
$$ = MakeFunctionSignatureNode($2, $7, $4, MakeFunctionModifiersNode(&modifier, 1), MakeEmptyGenericConstraintsNode());
}
FunctionDeclaration : FunctionSignature Body
{
$$ = MakeFunctionDeclarationNode($1, $2);
}
StructDeclaration : STRUCT Identifier LEFT_BRACE Declarations RIGHT_BRACE
{
$$ = MakeStructDeclarationNode($2, $4);
}
InterfaceDeclaration : INTERFACE Identifier LEFT_BRACE InterfaceChildren RIGHT_BRACE
{
$$ = MakeInterfaceDeclarationNode($2, $4);
}
InterfaceChild : FunctionSignature SEMICOLON
;
InterfaceChildren : InterfaceChild
{
$$ = StartDeclarationSequenceNode($1);
}
| InterfaceChildren InterfaceChild
{
$$ = AddDeclarationNode($1, $2);
}
;
Declaration : FunctionDeclaration
| VariableDeclaration SEMICOLON
;
Declarations : Declaration
{
$$ = StartDeclarationSequenceNode($1);
}
| Declarations Declaration
{
$$ = AddDeclarationNode($1, $2);
}
TopLevelDeclaration : StructDeclaration
| InterfaceDeclaration
;
TopLevelDeclarations : TopLevelDeclaration
{
$$ = StartDeclarationSequenceNode($1);
}
| TopLevelDeclarations TopLevelDeclaration
{
$$ = AddDeclarationNode($1, $2);
}
%%