forked from cosmonaut/wraith-lang
more parser progress
parent
d8df1c019a
commit
465daaa931
115
ast.h
115
ast.h
|
@ -1,19 +1,20 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Assignment,
|
||||
BinaryExpression,
|
||||
Boolean,
|
||||
Comment,
|
||||
Declaration,
|
||||
Expression,
|
||||
ForLoop,
|
||||
Identifier,
|
||||
Number,
|
||||
Return,
|
||||
String,
|
||||
StringLiteral,
|
||||
UnaryExpression
|
||||
} SyntaxKind;
|
||||
|
||||
|
@ -28,18 +29,22 @@ typedef enum
|
|||
Subtract
|
||||
} BinaryOperator;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Bool,
|
||||
Int,
|
||||
UInt,
|
||||
Float,
|
||||
Double,
|
||||
String
|
||||
} PrimitiveType;
|
||||
|
||||
typedef union
|
||||
{
|
||||
UnaryOperator unaryOperator;
|
||||
BinaryOperator binaryOperator;
|
||||
} Operator;
|
||||
|
||||
typedef union
|
||||
{
|
||||
const char *string;
|
||||
uint64_t number;
|
||||
} Value;
|
||||
|
||||
typedef struct Node
|
||||
{
|
||||
SyntaxKind syntaxKind;
|
||||
|
@ -50,18 +55,37 @@ typedef struct Node
|
|||
UnaryOperator unaryOperator;
|
||||
BinaryOperator binaryOperator;
|
||||
} operator;
|
||||
Value value;
|
||||
union
|
||||
{
|
||||
char *string;
|
||||
uint64_t number;
|
||||
} value;
|
||||
PrimitiveType type;
|
||||
} Node;
|
||||
|
||||
char* strdup (const char* s)
|
||||
{
|
||||
size_t slen = strlen(s);
|
||||
char* result = malloc(slen + 1);
|
||||
if(result == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(result, s, slen+1);
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* SyntaxKindString(SyntaxKind syntaxKind)
|
||||
{
|
||||
switch(syntaxKind)
|
||||
{
|
||||
case Assignment: return "Assignment";
|
||||
case BinaryExpression: return "BinaryExpression";
|
||||
case Declaration: return "Declaration";
|
||||
case Identifier: return "Identifier";
|
||||
case Number: return "Number";
|
||||
case String: return "String";
|
||||
case StringLiteral: return "StringLiteral";
|
||||
case UnaryExpression: return "UnaryExpression";
|
||||
default: return "Unknown";
|
||||
}
|
||||
|
@ -72,7 +96,7 @@ Node* MakeIdentifierNode(
|
|||
) {
|
||||
Node* node = (Node*) malloc(sizeof(Node));
|
||||
node->syntaxKind = Identifier;
|
||||
node->value.string = id;
|
||||
node->value.string = strdup(id);
|
||||
node->childCount = 0;
|
||||
return node;
|
||||
}
|
||||
|
@ -92,8 +116,8 @@ Node* MakeStringNode(
|
|||
const char *string
|
||||
) {
|
||||
Node* node = (Node*) malloc(sizeof(Node));
|
||||
node->syntaxKind = String;
|
||||
node->value.string = string;
|
||||
node->syntaxKind = StringLiteral;
|
||||
node->value.string = strdup(string);
|
||||
node->childCount = 0;
|
||||
return node;
|
||||
}
|
||||
|
@ -126,6 +150,43 @@ Node* MakeBinaryNode(
|
|||
return node;
|
||||
}
|
||||
|
||||
Node* MakeDeclarationNode(
|
||||
PrimitiveType type,
|
||||
const char *id
|
||||
) {
|
||||
Node* node = (Node*) malloc(sizeof(Node));
|
||||
node->syntaxKind = Declaration;
|
||||
node->type = type;
|
||||
node->value.string = strdup(id);
|
||||
node->childCount = 0;
|
||||
return node;
|
||||
}
|
||||
|
||||
Node* MakeAssignmentNode(
|
||||
Node *left,
|
||||
Node *right
|
||||
) {
|
||||
Node* node = (Node*) malloc(sizeof(Node));
|
||||
node->syntaxKind = Assignment;
|
||||
node->childCount = 2;
|
||||
node->children = malloc(sizeof(Node*) * 2);
|
||||
node->children[0] = left;
|
||||
node->children[1] = right;
|
||||
return node;
|
||||
}
|
||||
|
||||
static const char* PrimitiveTypeToString(PrimitiveType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Int: return "Int";
|
||||
case UInt: return "UInt";
|
||||
case Bool: return "Bool";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
static void PrintBinaryOperator(BinaryOperator expression)
|
||||
{
|
||||
switch (expression)
|
||||
|
@ -142,27 +203,43 @@ static void PrintBinaryOperator(BinaryOperator expression)
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
static void PrintNode(Node *node)
|
||||
static void PrintNode(Node *node, int tabCount)
|
||||
{
|
||||
printf("%s\n", SyntaxKindString(node->syntaxKind));
|
||||
uint32_t i;
|
||||
for (i = 0; i < tabCount; i += 1)
|
||||
{
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
printf("%s: ", SyntaxKindString(node->syntaxKind));
|
||||
switch (node->syntaxKind)
|
||||
{
|
||||
case BinaryExpression:
|
||||
PrintBinaryOperator(node->operator.binaryOperator);
|
||||
break;
|
||||
|
||||
case Declaration:
|
||||
printf("%s %s", PrimitiveTypeToString(node->type), node->value.string);
|
||||
break;
|
||||
|
||||
case Identifier:
|
||||
printf("%s", node->value.string);
|
||||
break;
|
||||
|
||||
case Number:
|
||||
printf("%lu\n", node->value.number);
|
||||
printf("%lu", node->value.number);
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void PrintTree(Node *node)
|
||||
void PrintTree(Node *node, uint32_t tabCount)
|
||||
{
|
||||
uint32_t i;
|
||||
PrintNode(node);
|
||||
PrintNode(node, tabCount);
|
||||
for (i = 0; i < node->childCount; i += 1)
|
||||
{
|
||||
PrintTree(node->children[i]);
|
||||
PrintTree(node->children[i], tabCount + 1);
|
||||
}
|
||||
}
|
||||
|
|
15
wraith.lex
15
wraith.lex
|
@ -1,11 +1,15 @@
|
|||
%{
|
||||
extern int yywrap() { return 1; }
|
||||
%}
|
||||
%option noyywrap
|
||||
|
||||
%%
|
||||
[0-9]+ return NUMBER;
|
||||
"int" return INT;
|
||||
"uint" return UINT;
|
||||
"float" return FLOAT;
|
||||
"double" return DOUBLE;
|
||||
"string" return STRING;
|
||||
"bool" return BOOL;
|
||||
[a-zA-Z][a-zA-Z0-9]* return ID;
|
||||
\"[a-zA-Z][a-zA-Z0-9]*\" return STRING;
|
||||
\"[a-zA-Z][a-zA-Z0-9]*\" return STRING_LITERAL;
|
||||
"+" return PLUS;
|
||||
"-" return MINUS;
|
||||
"*" return MULTIPLY;
|
||||
|
@ -30,6 +34,7 @@ extern int yywrap() { return 1; }
|
|||
"{" return LEFT_BRACE;
|
||||
"}" return RIGHT_BRACE;
|
||||
"//" return COMMENT;
|
||||
"\n" return NEWLINE;
|
||||
" " ;
|
||||
"\n" ;
|
||||
[ \t] ;
|
||||
%%
|
||||
|
|
107
wraith.y
107
wraith.y
|
@ -1,6 +1,25 @@
|
|||
%{
|
||||
#include <stdio.h>
|
||||
#include "ast.h"
|
||||
#define YYSTYPE struct Node*
|
||||
void yyerror(FILE *fp, char *s)
|
||||
{
|
||||
fprintf (stderr, "%s\n", s);
|
||||
}
|
||||
Node **statements;
|
||||
uint32_t statementCount;
|
||||
uint32_t i;
|
||||
%}
|
||||
|
||||
%token NUMBER
|
||||
%token ID
|
||||
%token INT
|
||||
%token UINT
|
||||
%token FLOAT
|
||||
%token DOUBLE
|
||||
%token STRING
|
||||
%token BOOL
|
||||
%token ID
|
||||
%token STRING_LITERAL
|
||||
%token PLUS
|
||||
%token MINUS
|
||||
%token MULTIPLY
|
||||
|
@ -27,25 +46,27 @@
|
|||
%token COMMENT
|
||||
%token NEWLINE
|
||||
|
||||
%parse-param { FILE* fp }
|
||||
|
||||
%left PLUS MINUS
|
||||
%left BANG
|
||||
%left LEFT_PAREN RIGHT_PAREN
|
||||
|
||||
%{
|
||||
#include "ast.h"
|
||||
#define YYSTYPE struct Node*
|
||||
%}
|
||||
|
||||
%%
|
||||
Main : Expression NEWLINE
|
||||
Program : Statements
|
||||
{
|
||||
PrintTree($1);
|
||||
for (i = 0; i < statementCount; i += 1)
|
||||
{
|
||||
PrintTree(statements[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
PrimaryExpression : ID
|
||||
Identifier : ID
|
||||
{
|
||||
$$ = MakeIdentifierNode(yytext);
|
||||
}
|
||||
|
||||
PrimaryExpression : Identifier
|
||||
| NUMBER
|
||||
{
|
||||
$$ = MakeNumberNode(yytext);
|
||||
|
@ -75,17 +96,71 @@ Expression : PrimaryExpression
|
|||
| UnaryExpression
|
||||
| BinaryExpression
|
||||
;
|
||||
|
||||
VariableDeclaration : INT ID
|
||||
{
|
||||
$$ = MakeDeclarationNode(Int, yytext);
|
||||
}
|
||||
| UINT ID
|
||||
{
|
||||
$$ = MakeDeclarationNode(UInt, yytext);
|
||||
}
|
||||
| FLOAT ID
|
||||
{
|
||||
$$ = MakeDeclarationNode(Float, yytext);
|
||||
}
|
||||
| DOUBLE ID
|
||||
{
|
||||
$$ = MakeDeclarationNode(Double, yytext);
|
||||
}
|
||||
| STRING ID
|
||||
{
|
||||
$$ = MakeDeclarationNode(String, yytext);
|
||||
}
|
||||
| BOOL ID
|
||||
{
|
||||
$$ = MakeDeclarationNode(Bool, yytext);
|
||||
}
|
||||
|
||||
AssignmentStatement : VariableDeclaration EQUAL Expression
|
||||
{
|
||||
$$ = MakeAssignmentNode($1, $3);
|
||||
}
|
||||
| Identifier EQUAL Expression
|
||||
{
|
||||
$$ = MakeAssignmentNode($1, $3);
|
||||
}
|
||||
|
||||
Statement : AssignmentStatement
|
||||
;
|
||||
|
||||
CompleteStatement : Statement SEMICOLON;
|
||||
|
||||
Statements : Statements CompleteStatement
|
||||
{
|
||||
statements = realloc(statements, statementCount + 1);
|
||||
statements[statementCount] = $2;
|
||||
statementCount += 1;
|
||||
}
|
||||
|
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
%%
|
||||
|
||||
#include "lex.yy.c"
|
||||
|
||||
/* yacc error handler */
|
||||
void yyerror(char *s)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
fprintf (stderr, "%s\n", s);
|
||||
}
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Please provide a file.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return yyparse();
|
||||
FILE *fp = fopen(argv[1], "r");
|
||||
yyin = fp;
|
||||
yyparse(fp);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue