some progress

This commit is contained in:
Ludwig Lehnert 2024-02-27 21:06:50 +01:00
parent 055a2c0ef7
commit 99ac38be63
15 changed files with 205 additions and 84 deletions

View File

@ -11,9 +11,12 @@
#include "Stmt/ExprStmt.h" #include "Stmt/ExprStmt.h"
#include "Stmt/FnDecl.h" #include "Stmt/FnDecl.h"
#include "Stmt/TraitDecl.h"
#include "Stmt/TypeDecl.h"
#include "Stmt/ValDecl.h" #include "Stmt/ValDecl.h"
#include "Type/Function.h" #include "Type/Function.h"
#include "Type/Generic.h"
#include "Type/Named.h" #include "Type/Named.h"
#include "Type/Tuple.h" #include "Type/Tuple.h"

View File

@ -13,6 +13,7 @@ namespace ast
~CallExpr() ~CallExpr()
{ {
delete callee;
for (auto &arg : args) for (auto &arg : args)
delete arg; delete arg;
} }

View File

@ -0,0 +1,19 @@
#pragma once
#include "AST/Base.h"
#include <string>
#include <vector>
namespace ast
{
class Closure : public Expr
{
public:
Closure(const std::vector<std::string> &args, const Expr *body)
: args(std::move(args)), body(body) {}
~Closure() { delete body; }
const std::vector<std::string> args;
const Expr *body;
};
}

View File

@ -0,0 +1,25 @@
#pragma once
#include "AST/Base.h"
#include <vector>
#include <string>
namespace ast
{
class FnDecl;
class TraitDecl : public Stmt
{
public:
TraitDecl(const std::string &name, const std::vector<FnDecl *> &traits)
: name(name), traits(std::move(traits)) {}
~TraitDecl()
{
for (auto &trait : traits)
delete trait;
}
const std::string name;
const std::vector<FnDecl *> traits;
};
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "AST/Base.h"
#include <vector>
#include <string>
namespace ast
{
class FnDecl;
typedef std::pair<std::string, Type *> TypeAttr;
class TypeDecl : public Stmt
{
public:
TypeDecl(const std::string &name, const std::vector<TypeAttr> &attrs, const std::vector<FnDecl *> &members)
: name(name), attrs(std::move(attrs)), members(std::move(members)) {}
~TypeDecl()
{
for (auto &attr : attrs)
delete attr.second;
for (auto &member : members)
delete member;
}
const std::string name;
const std::vector<TypeAttr> attrs;
const std::vector<FnDecl *> members;
};
}

View File

@ -0,0 +1,24 @@
#pragma once
#include "AST/Base.h"
#include <string>
#include <vector>
namespace ast
{
class GenericType : public Type
{
public:
GenericType(const std::string &name, const std::vector<Type *> &types)
: name(name), types(std::move(types)) {}
~GenericType()
{
for (auto &type : types)
delete type;
}
const std::string name;
const std::vector<Type *> types;
};
}

18
compiler/include/Parser.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include <string>
#include "AST/Def.h"
#include "parser.gen.h"
class Parser
{
public:
Parser() {}
ast::Module *parse(const std::string &file, const std::stringstream &input);
std::string file;
yy::location location;
ast::Module *module;
};

View File

@ -1,25 +0,0 @@
#pragma once
#include <string>
#include "AST/Def.h"
#include "parser.gen.h"
class ParserDriver
{
public:
ParserDriver() {}
~ParserDriver() { delete module; }
int parse(const std::string &input);
void startLexer();
void stopLexer();
std::string file;
yy::location location;
ast::Module *module;
};
#define YY_DECL yy::parser::symbol_type yylex(ParserDriver &driver)
YY_DECL;

View File

@ -1,6 +1,9 @@
%{ %{
#include "parser.gen.h" #include "parser.gen.h"
#include "ParserDriver.h" #include "Parser.h"
#undef YY_DECL
#define YY_DECL yy::parser::symbol_type yylex(Parser &driver)
#define yyterminate() yy::parser::make_END(yy::location()) #define yyterminate() yy::parser::make_END(yy::location())
@ -16,7 +19,7 @@ hexdigit [0-9a-fA-F]
letter [a-zA-Z] letter [a-zA-Z]
opchar ("+"|"-"|"*"|"/"|"%"|"!"|"&"|"$"|"§"|"|"|"="|"<"|">"|"?"|"~"|"#"|":"|"^"|"\\") opchar ("+"|"-"|"*"|"/"|"%"|"!"|"&"|"$"|"§"|"|"|"="|"<"|">"|"?"|"~"|"#"|":"|"^"|"\\"|".")
whitespace [ \n\t\r\v]+ whitespace [ \n\t\r\v]+
@ -33,9 +36,9 @@ whitespace [ \n\t\r\v]+
{opchar}+ { std::string text = yytext; {opchar}+ { std::string text = yytext;
if (text == "=") return _token(EQUALS); if (text == "=") return _token(EQUALS);
if (text == "->") return _token(RARR); if (text == "->") return _token(RARR);
if (text == ".") return _token(DOT);
return _token(OPERATOR); } return _token(OPERATOR); }
"." { return _token(DOT); }
"," { return _token(COMMA); } "," { return _token(COMMA); }
";" { return _token(SEMI); } ";" { return _token(SEMI); }
"(" { return _token(LPAREN); } "(" { return _token(LPAREN); }
@ -62,9 +65,3 @@ whitespace [ \n\t\r\v]+
{whitespace} { ; } {whitespace} { ; }
%% %%
void ParserDriver::startLexer() {
yy_scan_string(this->file.data());
}
void ParserDriver::stopLexer() {}

View File

@ -19,14 +19,15 @@
%code requires { %code requires {
#include "AST/Def.h" #include "AST/Def.h"
class ParserDriver; class Parser;
} }
%lex-param { ParserDriver &driver } %lex-param { Parser &driver }
%parse-param { ParserDriver &driver } %parse-param { Parser &driver }
%code { %code {
#include "ParserDriver.h" #include "Parser.h"
yy::parser::symbol_type yylex(Parser &driver);
} }
%token <long> INT "integer literal" %token <long> INT "integer literal"
@ -70,7 +71,8 @@ class ParserDriver;
blockStmt blockStmt
; ;
%type <ast::FnDecl *> extFnDecl fnDecl; %type <std::vector<ast::FnDecl *>> fnDecls fnDecls0;
%type <ast::FnDecl *> fnDecl fnDef;
%type <ast::ValDecl *> valDecl; %type <ast::ValDecl *> valDecl;
%type <std::vector<ast::Type *>> %type <std::vector<ast::Type *>>
@ -79,14 +81,9 @@ class ParserDriver;
fnTypeArgs fnTypeArgs
; ;
%type <ast::Type *> %type <ast::Type *> type type1;
type
;
%type <std::vector<ast::Expr *>> %type <std::vector<ast::Expr *>> exprs args;
exprs
args
;
%type <ast::Expr *> %type <ast::Expr *>
expr expr
@ -98,10 +95,7 @@ class ParserDriver;
; ;
%type <ast::FnArg> fnArg; %type <ast::FnArg> fnArg;
%type <std::vector<ast::FnArg>> %type <std::vector<ast::FnArg>> fnArgs fnArgs0;
fnArgs
fnArgs0
;
%type <std::vector<std::string>> %type <std::vector<std::string>>
lambdaArgs lambdaArgs
@ -110,6 +104,7 @@ class ParserDriver;
%type <std::string> %type <std::string>
moduleName moduleName
type0
operator operator
identifier identifier
keyword keyword
@ -121,11 +116,14 @@ class ParserDriver;
imports imports
; ;
%type <ast::TraitDecl *> traitDecl;
%type <ast::TypeDecl *> typeDecl;
%start module %start module
%% %%
module: imports topLevelStmts { driver.module = new ast::Module($2); } module: imports topLevelStmts { driver.module = new ast::Module($1, $2); }
; ;
@ -144,14 +142,15 @@ moduleName: identifier { $$ = $1; }
| moduleName "." identifier { $$ = $1 + $2 + $3; } | moduleName "." identifier { $$ = $1 + $2 + $3; }
; ;
topLevelStmts: topLevelStmt { $$.push_back($1); } topLevelStmts: topLevelStmt { $$.push_back($1); }
| topLevelStmts topLevelStmt { $1.push_back($2); $$ = std::move($1); } | topLevelStmts topLevelStmt { $1.push_back($2); $$ = std::move($1); }
; ;
topLevelStmt: fnDecl { $$ = $1; } topLevelStmt: fnDef { $$ = $1; }
| extFnDecl { $$ = $1; } | fnDecl { $$ = $1; }
| valDecl { $$ = $1; } | valDecl { $$ = $1; }
| typeDecl { $$ = $1; }
| traitDecl { $$ = $1; }
; ;
blockStmts: blockStmt { $$.push_back($1); } blockStmts: blockStmt { $$.push_back($1); }
@ -159,19 +158,33 @@ blockStmts: blockStmt { $$.push_back($1); }
; ;
blockStmt: valDecl { $$ = $1; } blockStmt: valDecl { $$ = $1; }
| fnDecl { $$ = $1; } | fnDef { $$ = $1; }
| expr ";" { $$ = new ast::ExprStmt($1); } | expr ";" { $$ = new ast::ExprStmt($1); }
; ;
traitDecl: TRAIT identifier "=" "{" fnDecls "}" { $$ = new ast::TraitDecl($2, $5); }
;
typeDecl: TYPE identifier "=" "(" fnArgs ")" "{" fnDecls "}" { $$ = new ast::TypeDecl($2, $5, $8); }
;
fnDecls: %empty { ; }
| fnDecls0 { $$ = std::move($1); }
;
fnDecls0: fnDecl { $$.push_back($1); }
| fnDecls0 fnDecl { $1.push_back($2); $$ = std::move($1); }
;
valDecl: VAL identifier "=" expr ";" { $$ = new ast::ValDecl($2, nullptr, $4); } valDecl: VAL identifier "=" expr ";" { $$ = new ast::ValDecl($2, nullptr, $4); }
| VAL identifier type "=" expr ";" { $$ = new ast::ValDecl($2, $3, $5); } | VAL identifier type "=" expr ";" { $$ = new ast::ValDecl($2, $3, $5); }
; ;
fnDecl: FN identifier "[" fnArgs "]" type "=" expr ";" { $$ = new ast::FnDecl($2, $4, $6, $8); } fnDef : FN identifier "[" fnArgs "]" type "=" expr ";" { $$ = new ast::FnDecl($2, $4, $6, $8); }
; ;
extFnDecl: DECLARE FN identifier "[" fnArgs "]" type ";" { $$ = new ast::FnDecl($3, $5, $7, nullptr); } fnDecl: FN identifier "[" fnArgs "]" type ";" { $$ = new ast::FnDecl($2, $4, $6, nullptr); }
; ;
fnArgs: %empty { ; } fnArgs: %empty { ; }
| fnArgs0 { $$ = std::move($1); } | fnArgs0 { $$ = std::move($1); }
@ -188,12 +201,18 @@ types: type { $$.push_back($1); }
| types "," type { $1.push_back($3); $$ = std::move($1); } | types "," type { $1.push_back($3); $$ = std::move($1); }
; ;
type: identifier { $$ = new ast::NamedType($1); } type: type1
| "(" type ")" { $$ = $2; } | "(" type ")" { $$ = $2; }
| "(" tupleTypes ")" { $$ = new ast::TupleType($2); } | "(" tupleTypes ")" { $$ = new ast::TupleType($2); }
| "[" fnTypeArgs "]" "->" type { $$ = new ast::FunctionType($2, $5); } | "[" fnTypeArgs "]" "->" type { $$ = new ast::FunctionType($2, $5); }
; ;
type1: type0 { $$ = new ast::NamedType($1); }
| type0 "{" types "}" { $$ = new ast::GenericType($1, $3); }
;
type0: identifier;
tupleTypes: type "," type { $$.push_back($1); $$.push_back($3); } tupleTypes: type "," type { $$.push_back($1); $$.push_back($3); }
| tupleTypes "," type { $1.push_back($3); $$ = std::move($1); } | tupleTypes "," type { $1.push_back($3); $$ = std::move($1); }
; ;
@ -210,8 +229,8 @@ expr: expr3 { $$ = $1; }
; ;
expr3: expr2 { $$ = $1; } expr3: expr2 { $$ = $1; }
| "[" lambdaArgs "]" "->" expr { $$ = NULL; } | "[" lambdaArgs "]" "->" expr { $$ = nullptr; }
| "{" blockStmts "}" { $$ = new ast::BlockExpr($2); } | "{" blockStmts "}" { $$ = new ast::BlockExpr($2); }
; ;
expr2: expr1 { $$ = $1; } expr2: expr1 { $$ = $1; }
@ -226,6 +245,7 @@ expr0: literal { $$ = $1; }
| identifier { $$ = new ast::Identifier($1); } | identifier { $$ = new ast::Identifier($1); }
| expr0 "[" args "]" { $$ = new ast::CallExpr($1, $3); } | expr0 "[" args "]" { $$ = new ast::CallExpr($1, $3); }
| "(" expr ")" { $$ = new ast::PrefExpr($2); } | "(" expr ")" { $$ = new ast::PrefExpr($2); }
| expr0 "." identifier { $$ = $1; }
; ;
lambdaArgs: %empty { ; } lambdaArgs: %empty { ; }

20
compiler/src/Parser.cpp Normal file
View File

@ -0,0 +1,20 @@
#include "Parser.h"
#include <sstream>
#include <fstream>
void yy_scan_string(const char *);
ast::Module *Parser::parse(const std::string &file, const std::stringstream &input)
{
module = nullptr;
this->file = file;
location.initialize(&file);
yy_scan_string(input.str().data());
int res = yy::parser(*this)();
return module;
}

View File

@ -1,14 +0,0 @@
#include "ParserDriver.h"
int ParserDriver::parse(const std::string &input)
{
file = input;
location.initialize(&file);
startLexer();
yy::parser parse(*this);
int res = parse();
stopLexer();
return res;
}

View File

@ -1,10 +1,10 @@
#include "ParserDriver.h" #include "Parser.h"
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
std::stringstream readFile(const std::string &path) static std::stringstream readFile(const std::string &path)
{ {
std::ifstream t(path); std::ifstream t(path);
std::stringstream buffer; std::stringstream buffer;
@ -21,10 +21,10 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
auto buf = readFile(argv[1]); auto module = Parser().parse(argv[1], readFile(argv[1]));
auto parser = ParserDriver();
parser.parse(buf.str());
auto fn = (ast::FnDecl *)parser.module->stmts.at(0); auto fn = (ast::FnDecl *)module->stmts.at(0);
std::cout << fn->name << std::endl; std::cout << fn->name << std::endl;
delete module;
} }

View File

@ -3,7 +3,9 @@ import test.test;
fn main[] Int = 42; fn main[] Int = 42;
fn test[b Int] Int = { fn test[b Int] Int = {
fn helper[] Int = 10; fn helper[] Int = b;
20 * b; 20 * helper[];
}; };
fn size[vals List{Int}] Int = vals.size[];

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
#include "int.h" #include "int.h"
#include "bool.h" #include "bool.h"