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 <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
Assignment,
|
Assignment,
|
||||||
BinaryExpression,
|
BinaryExpression,
|
||||||
Boolean,
|
|
||||||
Comment,
|
Comment,
|
||||||
|
Declaration,
|
||||||
Expression,
|
Expression,
|
||||||
ForLoop,
|
ForLoop,
|
||||||
Identifier,
|
Identifier,
|
||||||
Number,
|
Number,
|
||||||
Return,
|
Return,
|
||||||
String,
|
StringLiteral,
|
||||||
UnaryExpression
|
UnaryExpression
|
||||||
} SyntaxKind;
|
} SyntaxKind;
|
||||||
|
|
||||||
|
@ -28,18 +29,22 @@ typedef enum
|
||||||
Subtract
|
Subtract
|
||||||
} BinaryOperator;
|
} BinaryOperator;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Bool,
|
||||||
|
Int,
|
||||||
|
UInt,
|
||||||
|
Float,
|
||||||
|
Double,
|
||||||
|
String
|
||||||
|
} PrimitiveType;
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
UnaryOperator unaryOperator;
|
UnaryOperator unaryOperator;
|
||||||
BinaryOperator binaryOperator;
|
BinaryOperator binaryOperator;
|
||||||
} Operator;
|
} Operator;
|
||||||
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
const char *string;
|
|
||||||
uint64_t number;
|
|
||||||
} Value;
|
|
||||||
|
|
||||||
typedef struct Node
|
typedef struct Node
|
||||||
{
|
{
|
||||||
SyntaxKind syntaxKind;
|
SyntaxKind syntaxKind;
|
||||||
|
@ -50,18 +55,37 @@ typedef struct Node
|
||||||
UnaryOperator unaryOperator;
|
UnaryOperator unaryOperator;
|
||||||
BinaryOperator binaryOperator;
|
BinaryOperator binaryOperator;
|
||||||
} operator;
|
} operator;
|
||||||
Value value;
|
union
|
||||||
|
{
|
||||||
|
char *string;
|
||||||
|
uint64_t number;
|
||||||
|
} value;
|
||||||
|
PrimitiveType type;
|
||||||
} Node;
|
} 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)
|
const char* SyntaxKindString(SyntaxKind syntaxKind)
|
||||||
{
|
{
|
||||||
switch(syntaxKind)
|
switch(syntaxKind)
|
||||||
{
|
{
|
||||||
case Assignment: return "Assignment";
|
case Assignment: return "Assignment";
|
||||||
case BinaryExpression: return "BinaryExpression";
|
case BinaryExpression: return "BinaryExpression";
|
||||||
|
case Declaration: return "Declaration";
|
||||||
case Identifier: return "Identifier";
|
case Identifier: return "Identifier";
|
||||||
case Number: return "Number";
|
case Number: return "Number";
|
||||||
case String: return "String";
|
case StringLiteral: return "StringLiteral";
|
||||||
case UnaryExpression: return "UnaryExpression";
|
case UnaryExpression: return "UnaryExpression";
|
||||||
default: return "Unknown";
|
default: return "Unknown";
|
||||||
}
|
}
|
||||||
|
@ -72,7 +96,7 @@ Node* MakeIdentifierNode(
|
||||||
) {
|
) {
|
||||||
Node* node = (Node*) malloc(sizeof(Node));
|
Node* node = (Node*) malloc(sizeof(Node));
|
||||||
node->syntaxKind = Identifier;
|
node->syntaxKind = Identifier;
|
||||||
node->value.string = id;
|
node->value.string = strdup(id);
|
||||||
node->childCount = 0;
|
node->childCount = 0;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -92,8 +116,8 @@ Node* MakeStringNode(
|
||||||
const char *string
|
const char *string
|
||||||
) {
|
) {
|
||||||
Node* node = (Node*) malloc(sizeof(Node));
|
Node* node = (Node*) malloc(sizeof(Node));
|
||||||
node->syntaxKind = String;
|
node->syntaxKind = StringLiteral;
|
||||||
node->value.string = string;
|
node->value.string = strdup(string);
|
||||||
node->childCount = 0;
|
node->childCount = 0;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -126,6 +150,43 @@ Node* MakeBinaryNode(
|
||||||
return node;
|
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)
|
static void PrintBinaryOperator(BinaryOperator expression)
|
||||||
{
|
{
|
||||||
switch (expression)
|
switch (expression)
|
||||||
|
@ -142,27 +203,43 @@ static void PrintBinaryOperator(BinaryOperator expression)
|
||||||
printf("\n");
|
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)
|
switch (node->syntaxKind)
|
||||||
{
|
{
|
||||||
case BinaryExpression:
|
case BinaryExpression:
|
||||||
PrintBinaryOperator(node->operator.binaryOperator);
|
PrintBinaryOperator(node->operator.binaryOperator);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Declaration:
|
||||||
|
printf("%s %s", PrimitiveTypeToString(node->type), node->value.string);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Identifier:
|
||||||
|
printf("%s", node->value.string);
|
||||||
|
break;
|
||||||
|
|
||||||
case Number:
|
case Number:
|
||||||
printf("%lu\n", node->value.number);
|
printf("%lu", node->value.number);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintTree(Node *node)
|
void PrintTree(Node *node, uint32_t tabCount)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
PrintNode(node);
|
PrintNode(node, tabCount);
|
||||||
for (i = 0; i < node->childCount; i += 1)
|
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 @@
|
||||||
%{
|
%option noyywrap
|
||||||
extern int yywrap() { return 1; }
|
|
||||||
%}
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
[0-9]+ return NUMBER;
|
[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 ID;
|
||||||
\"[a-zA-Z][a-zA-Z0-9]*\" return STRING;
|
\"[a-zA-Z][a-zA-Z0-9]*\" return STRING_LITERAL;
|
||||||
"+" return PLUS;
|
"+" return PLUS;
|
||||||
"-" return MINUS;
|
"-" return MINUS;
|
||||||
"*" return MULTIPLY;
|
"*" return MULTIPLY;
|
||||||
|
@ -30,6 +34,7 @@ extern int yywrap() { return 1; }
|
||||||
"{" return LEFT_BRACE;
|
"{" return LEFT_BRACE;
|
||||||
"}" return RIGHT_BRACE;
|
"}" return RIGHT_BRACE;
|
||||||
"//" return COMMENT;
|
"//" return COMMENT;
|
||||||
"\n" return NEWLINE;
|
" " ;
|
||||||
|
"\n" ;
|
||||||
[ \t] ;
|
[ \t] ;
|
||||||
%%
|
%%
|
||||||
|
|
105
wraith.y
105
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 NUMBER
|
||||||
%token ID
|
%token INT
|
||||||
|
%token UINT
|
||||||
|
%token FLOAT
|
||||||
|
%token DOUBLE
|
||||||
%token STRING
|
%token STRING
|
||||||
|
%token BOOL
|
||||||
|
%token ID
|
||||||
|
%token STRING_LITERAL
|
||||||
%token PLUS
|
%token PLUS
|
||||||
%token MINUS
|
%token MINUS
|
||||||
%token MULTIPLY
|
%token MULTIPLY
|
||||||
|
@ -27,25 +46,27 @@
|
||||||
%token COMMENT
|
%token COMMENT
|
||||||
%token NEWLINE
|
%token NEWLINE
|
||||||
|
|
||||||
|
%parse-param { FILE* fp }
|
||||||
|
|
||||||
%left PLUS MINUS
|
%left PLUS MINUS
|
||||||
%left BANG
|
%left BANG
|
||||||
%left LEFT_PAREN RIGHT_PAREN
|
%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);
|
$$ = MakeIdentifierNode(yytext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrimaryExpression : Identifier
|
||||||
| NUMBER
|
| NUMBER
|
||||||
{
|
{
|
||||||
$$ = MakeNumberNode(yytext);
|
$$ = MakeNumberNode(yytext);
|
||||||
|
@ -75,17 +96,71 @@ Expression : PrimaryExpression
|
||||||
| UnaryExpression
|
| UnaryExpression
|
||||||
| BinaryExpression
|
| 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"
|
#include "lex.yy.c"
|
||||||
|
|
||||||
/* yacc error handler */
|
int main(int argc, char *argv[])
|
||||||
void yyerror(char *s)
|
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s\n", s);
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
printf("Please provide a file.\n");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
FILE *fp = fopen(argv[1], "r");
|
||||||
{
|
yyin = fp;
|
||||||
return yyparse();
|
yyparse(fp);
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue