added project files
This commit is contained in:
commit
9655c05697
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
build/
|
76
.vscode/settings.json
vendored
Normal file
76
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
{
|
||||
"[yacc]": {
|
||||
"problems.decorations.enabled": false,
|
||||
},
|
||||
"files.associations": {
|
||||
"*.embeddedhtml": "html",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"format": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"span": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stdfloat": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp"
|
||||
},
|
||||
}
|
2
README.md
Normal file
2
README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# plsm
|
||||
Mainly functional general purpose programming language
|
1
compiler/.gitignore
vendored
Normal file
1
compiler/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.gen.*
|
28
compiler/CMakeLists.txt
Normal file
28
compiler/CMakeLists.txt
Normal file
@ -0,0 +1,28 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
|
||||
project(plasmatum)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(SOURCE_DIR ${CMAKE_SOURCE_DIR}/src)
|
||||
set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include)
|
||||
|
||||
find_package(FLEX REQUIRED)
|
||||
find_package(BISON REQUIRED)
|
||||
|
||||
BISON_TARGET(parser
|
||||
${CMAKE_SOURCE_DIR}/parser.yy
|
||||
${SOURCE_DIR}/parser.gen.cpp
|
||||
DEFINES_FILE ${INCLUDE_DIR}/parser.gen.h)
|
||||
|
||||
FLEX_TARGET(lexer
|
||||
${CMAKE_SOURCE_DIR}/lexer.ll
|
||||
${SOURCE_DIR}/lexer.gen.cpp)
|
||||
|
||||
ADD_FLEX_BISON_DEPENDENCY(lexer parser)
|
||||
|
||||
file(GLOB_RECURSE sources ${SOURCE_DIR}/*.cpp)
|
||||
set(sources ${sources} ${FLEX_lexer_OUTPUTS})
|
||||
set(sources ${sources} ${BISON_parser_OUTPUT_SOURCE})
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/include)
|
||||
add_executable(plsm ${sources})
|
49
compiler/include/AST.h
Normal file
49
compiler/include/AST.h
Normal file
@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class Expr;
|
||||
|
||||
class ASTNode
|
||||
{
|
||||
};
|
||||
|
||||
class Stmt : public ASTNode
|
||||
{
|
||||
};
|
||||
|
||||
class Decl : public Stmt
|
||||
{
|
||||
public:
|
||||
Decl(const std::string &identifier, const Expr *value)
|
||||
: identifier(identifier), value(value) {}
|
||||
|
||||
const std::string identifier;
|
||||
const Expr *value;
|
||||
};
|
||||
|
||||
class Expr : public ASTNode
|
||||
{
|
||||
};
|
||||
|
||||
class IntValue : public Expr
|
||||
{
|
||||
public:
|
||||
const long value;
|
||||
IntValue(const long value) : value(value) {}
|
||||
};
|
||||
|
||||
class FloatValue : public Expr
|
||||
{
|
||||
public:
|
||||
const double value;
|
||||
FloatValue(const double value) : value(value) {}
|
||||
};
|
||||
|
||||
class Function : public Expr
|
||||
{
|
||||
};
|
||||
|
||||
class List : public Expr
|
||||
{
|
||||
};
|
22
compiler/include/ASTVisitor.h
Normal file
22
compiler/include/ASTVisitor.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "AST.h"
|
||||
|
||||
template <typename T>
|
||||
class ASTVisitor
|
||||
{
|
||||
virtual T visit(const ASTNode *node)
|
||||
{
|
||||
if (IntValue *cnode = dynamic_cast<IntValue *>(node))
|
||||
return visitIntValue(cnode);
|
||||
else if (FloatValue *cnode = dynamic_cast<FloatValue *>(node))
|
||||
return visitFloatValue(cnode);
|
||||
|
||||
throw std::logic_error("not implemented");
|
||||
}
|
||||
|
||||
virtual T visitIntValue(const IntValue *node);
|
||||
virtual T visitFloatValue(const IntValue *node);
|
||||
};
|
23
compiler/include/ParserDriver.h
Normal file
23
compiler/include/ParserDriver.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "AST.h"
|
||||
#include "parser.gen.h"
|
||||
|
||||
class ParserDriver
|
||||
{
|
||||
public:
|
||||
ParserDriver() {}
|
||||
|
||||
int parse(const std::string &input);
|
||||
|
||||
void startLexer();
|
||||
void stopLexer();
|
||||
|
||||
std::string file;
|
||||
yy::location location;
|
||||
};
|
||||
|
||||
#define YY_DECL yy::parser::symbol_type yylex(ParserDriver &driver)
|
||||
YY_DECL;
|
57
compiler/lexer.ll
Normal file
57
compiler/lexer.ll
Normal file
@ -0,0 +1,57 @@
|
||||
%{
|
||||
#include "parser.gen.h"
|
||||
#include "ParserDriver.h"
|
||||
|
||||
#define yyterminate() yy::parser::make_END(yy::location())
|
||||
|
||||
#define _token(token) yy::parser::make_##token(driver.location)
|
||||
%}
|
||||
|
||||
%option noyywrap nounput noinput batch debug
|
||||
|
||||
digit [0-9]
|
||||
bindigit [0-1]
|
||||
octdigit [0-7]
|
||||
hexdigit [0-9a-fA-F]
|
||||
|
||||
letter [a-zA-Z]
|
||||
|
||||
whitespace [ \n\t\r\v]+
|
||||
|
||||
%%
|
||||
|
||||
"0b"{bindigit}+ { return yy::parser::make_INT(std::strtol(yytext, NULL, 2), driver.location); }
|
||||
"0o"{octdigit}+ { return yy::parser::make_INT(std::strtol(yytext, NULL, 8), driver.location); }
|
||||
"0x"{hexdigit}+ { return yy::parser::make_INT(std::strtol(yytext, NULL, 16), driver.location); }
|
||||
{digit}+ { return yy::parser::make_INT(std::strtol(yytext, NULL, 10), driver.location); }
|
||||
|
||||
{digit}*"."{digit}+ { return yy::parser::make_FLOAT(std::strtod(yytext, NULL), driver.location); }
|
||||
|
||||
// TODO: operator '==' won't work this way
|
||||
"->" { return _token(R_ARR); }
|
||||
"<-" { return _token(L_ARR); }
|
||||
";" { return _token(SEMI); }
|
||||
"=" { return _token(EQUALS); }
|
||||
|
||||
("+"|"-"|"*"|"/"|"%"|"!"|"&"|"$"|"§"|"|"|"="|"<"|">"|"?"|"~"|"#"|":"|"^"|"\\")+ { return _token(OPERATOR); }
|
||||
|
||||
|
||||
"fn" { return _token(FN); }
|
||||
"unop" { return _token(UNOP); }
|
||||
"binop" { return _token(BINOP); }
|
||||
"val" { return _token(VAL); }
|
||||
"import" { return _token(IMPORT); }
|
||||
"declare" { return _token(DECLARE); }
|
||||
|
||||
|
||||
{letter}({digit}|{letter})* { return yy::parser::make_IDENTIFIER(yytext, driver.location); }
|
||||
|
||||
{whitespace} { ; }
|
||||
|
||||
%%
|
||||
|
||||
void ParserDriver::startLexer() {
|
||||
yy_scan_string(this->file.data());
|
||||
}
|
||||
|
||||
void ParserDriver::stopLexer() {}
|
106
compiler/parser.yy
Normal file
106
compiler/parser.yy
Normal file
@ -0,0 +1,106 @@
|
||||
%require "3.8"
|
||||
%language "c++"
|
||||
|
||||
%header
|
||||
|
||||
%define api.token.raw
|
||||
%define api.value.type variant
|
||||
%define api.token.constructor
|
||||
%define api.token.prefix {TOK_}
|
||||
|
||||
%define parse.assert
|
||||
%define parse.trace
|
||||
%define parse.error detailed
|
||||
%define parse.lac full
|
||||
|
||||
%locations
|
||||
%define api.location.file "../include/location.gen.h"
|
||||
%define api.location.include {"location.gen.h"}
|
||||
|
||||
%code requires {
|
||||
#include "AST.h"
|
||||
class ParserDriver;
|
||||
}
|
||||
|
||||
%lex-param { ParserDriver &driver }
|
||||
%parse-param { ParserDriver &driver }
|
||||
|
||||
%code {
|
||||
#include "ParserDriver.h"
|
||||
}
|
||||
|
||||
%token <long> INT "integer literal"
|
||||
%token <double> FLOAT "float literal"
|
||||
|
||||
%token <std::string> OPERATOR "operator";
|
||||
%token <std::string> IDENTIFIER "identifier"
|
||||
|
||||
%token L_ARR "<-"
|
||||
%token R_ARR "->"
|
||||
%token EQUALS "="
|
||||
%token SEMI ";"
|
||||
|
||||
%token
|
||||
FN "fn"
|
||||
UNOP "unop"
|
||||
BINOP "binop"
|
||||
VAL "val"
|
||||
IMPORT "import"
|
||||
DECLARE "declare"
|
||||
;
|
||||
|
||||
%token END 0 "end of file"
|
||||
|
||||
%type <std::vector<Stmt *>> stmts;
|
||||
%type <Stmt *> stmt;
|
||||
%type <Decl *> decl;
|
||||
%type <Expr *> expr;
|
||||
%type <Value *> literal;
|
||||
|
||||
%type <std::string> operator;
|
||||
%type <std::string> identifier;
|
||||
%type <std::string> keyword;
|
||||
|
||||
%%
|
||||
|
||||
module: stmts;
|
||||
|
||||
stmts: stmt { $$ = std::vector<Stmt *>(); $$.push_back($1); }
|
||||
| stmts stmt { $1.push_back($2); $$ = std::move($1); }
|
||||
;
|
||||
|
||||
stmt: decl { $$ = $1; }
|
||||
;
|
||||
|
||||
decl: VAL identifier "=" expr ";" { $$ = new Decl($2, $4); }
|
||||
;
|
||||
|
||||
expr: literal { $$ = $1; }
|
||||
;
|
||||
|
||||
literal: INT { $$ = new IntValue($1); }
|
||||
| FLOAT { $$ = new FloatValue($1); }
|
||||
;
|
||||
|
||||
operator: L_ARR { $$ = $1; }
|
||||
| R_ARR { $$ = $1; }
|
||||
| EQUALS { $$ = $1; }
|
||||
| OPERATOR { $$ = $1; }
|
||||
;
|
||||
|
||||
identifier: keyword { $$ = $1; }
|
||||
| IDENTIFIER { $$ = $1; }
|
||||
;
|
||||
|
||||
keyword: FN { $$ = $1; }
|
||||
| UNOP { $$ = $1; }
|
||||
| BINOP { $$ = $1; }
|
||||
| IMPORT { $$ = $1; }
|
||||
| DECLARE { $$ = $1; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void yy::parser::error (const location_type& l, const std::string& m) {
|
||||
std::cerr << l << ": " << m << '\n';
|
||||
}
|
14
compiler/src/ParserDriver.cpp
Normal file
14
compiler/src/ParserDriver.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#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;
|
||||
}
|
5
compiler/src/main.cpp
Normal file
5
compiler/src/main.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include <string>
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
30
examples/stdlib.plsm
Normal file
30
examples/stdlib.plsm
Normal file
@ -0,0 +1,30 @@
|
||||
type Bool = class {
|
||||
declare unop ! -> Bool;
|
||||
|
||||
declare binop &&(b Bool) -> Bool;
|
||||
declare binop ||(b Bool) -> Bool;
|
||||
};
|
||||
|
||||
type Int = class {
|
||||
declare unop + -> Int;
|
||||
declare unop - -> Int;
|
||||
|
||||
declare binop ==(b Int) -> Bool;
|
||||
declare binop !=(b Int) -> Bool;
|
||||
declare binop >(b Int) -> Bool;
|
||||
declare binop <(b Int) -> Bool;
|
||||
declare binop >=(b Int) -> Bool;
|
||||
declare binop <=(b Int) -> Bool;
|
||||
|
||||
declare binop +(b Int) -> Int;
|
||||
declare binop -(b Int) -> Int;
|
||||
declare binop *(b Int) -> Int;
|
||||
declare binop /(b Int) -> Int;
|
||||
declare binop %(b Int) -> Int;
|
||||
|
||||
declare fn str() -> String;
|
||||
};
|
||||
|
||||
type String = class (data List[Char]) {
|
||||
|
||||
}
|
9
lib/CMakeLists.txt
Normal file
9
lib/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
|
||||
project(libplsm C)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
file(GLOB_RECURSE sources ${CMAKE_SOURCE_DIR}/src/*.c)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/include)
|
||||
add_library(libplsm SHARED ${sources})
|
6
lib/include/function.h
Normal file
6
lib/include/function.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
} function_t;
|
16
lib/include/list.h
Normal file
16
lib/include/list.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "type.h"
|
||||
#include "value.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
value_t *value;
|
||||
list_node_t *next;
|
||||
} list_node_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
type_t *type;
|
||||
list_node_t *head;
|
||||
} list_t;
|
19
lib/include/macros.h
Normal file
19
lib/include/macros.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define DIE \
|
||||
{ \
|
||||
exit(EXIT_FAILURE); \
|
||||
}
|
||||
|
||||
#define DIE_ERRNO(action) \
|
||||
{ \
|
||||
perror(action); \
|
||||
DIE; \
|
||||
}
|
||||
|
||||
#define MODINIT(module) void plsmmod_##module##_init()
|
||||
|
||||
#define LIB(name) plsmlib_##name
|
14
lib/include/type.h
Normal file
14
lib/include/type.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
typedef struct type_t type_t;
|
||||
|
||||
typedef struct type_t
|
||||
{
|
||||
type_t *base;
|
||||
int opaque;
|
||||
char *name;
|
||||
} type_t;
|
||||
|
||||
type_t *LIB(makeType)(type_t *base, int opaque, char *name);
|
9
lib/include/value.h
Normal file
9
lib/include/value.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "type.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
type_t *type;
|
||||
void *value;
|
||||
} value_t;
|
1
lib/src/function.c
Normal file
1
lib/src/function.c
Normal file
@ -0,0 +1 @@
|
||||
#include "function.h"
|
5
lib/src/module.c
Normal file
5
lib/src/module.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include "macros.h"
|
||||
|
||||
MODINIT(stdlib)
|
||||
{
|
||||
}
|
16
lib/src/type.c
Normal file
16
lib/src/type.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include "type.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
type_t *LIB(makeType)(type_t *base, int opaque, char *name)
|
||||
{
|
||||
type_t *type = malloc(sizeof(type_t));
|
||||
if (!type)
|
||||
DIE_ERRNO("malloc");
|
||||
|
||||
type->base = base;
|
||||
type->opaque = opaque;
|
||||
type->name = name;
|
||||
|
||||
return type;
|
||||
}
|
12
lib/src/types.c
Normal file
12
lib/src/types.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include "type.h"
|
||||
|
||||
type_t *LIB(typeAny), *LIB(typeNum), *LIB(typeInt), *LIB(typeFloat);
|
||||
|
||||
void LIB(initTypes)()
|
||||
{
|
||||
LIB(typeAny) = LIB(makeType)(NULL, "Any");
|
||||
|
||||
LIB(typeNum) = LIB(makeType)(LIB(typeAny), "Num");
|
||||
LIB(typeInt) = LIB(makeType)(LIB(typeNum), "Int");
|
||||
LIB(typeFloat) = LIB(makeType)(LIB(typeNum), "Float");
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user