Skip to content

Commit 5690759

Browse files
committed
Some initial things
1 parent ea85e20 commit 5690759

File tree

15 files changed

+915
-31
lines changed

15 files changed

+915
-31
lines changed

.gitignore

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,7 @@
1-
# Prerequisites
2-
*.d
3-
4-
# Compiled Object files
5-
*.slo
6-
*.lo
71
*.o
8-
*.obj
9-
10-
# Precompiled Headers
11-
*.gch
12-
*.pch
13-
14-
# Compiled Dynamic libraries
15-
*.so
16-
*.dylib
17-
*.dll
18-
19-
# Fortran module files
20-
*.mod
21-
*.smod
22-
23-
# Compiled Static libraries
24-
*.lai
25-
*.la
26-
*.a
27-
*.lib
28-
29-
# Executables
30-
*.exe
31-
*.out
32-
*.app
2+
c--
3+
.vscode
4+
src/bison.output
5+
include/bison.h
6+
src/flex.cpp
7+
src/bison.cpp

Makefile

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
COMPILER ?= clang++
2+
OPTIMIZATION ?= -O0 -g
3+
STANDARD ?= c++20
4+
WARNINGS ?= -Wall -Wextra
5+
CFLAGS := -std=$(STANDARD) $(OPTIMIZATION) $(WARNINGS) -Iinclude
6+
OUTPUT ?= c--
7+
8+
LEXERCPP := src/flex.cpp
9+
PARSERCPP := src/bison.cpp
10+
PARSERHDR := include/bison.h
11+
LEXERSRC := src/lexer.l
12+
PARSERSRC := src/parser.y
13+
FLEXPREFIX := cmm
14+
15+
LEXFLAGS := -Wno-sign-compare -Wno-register
16+
BISONFLAGS := --color=always
17+
18+
SOURCES := $(shell find src/**/*.cpp src/*.cpp) $(LEXERCPP) $(PARSERCPP)
19+
OBJECTS := $(SOURCES:.cpp=.o)
20+
21+
.PHONY: all test clean
22+
23+
all: $(OUTPUT)
24+
25+
$(OUTPUT): $(OBJECTS)
26+
$(COMPILER) -o $@ $^ $(LDFLAGS)
27+
28+
%.o: %.cpp $(PARSERHDR)
29+
$(COMPILER) $(CFLAGS) -c $< -o $@
30+
31+
$(LEXERCPP): $(LEXERSRC) $(PARSERHDR)
32+
flex --prefix=$(FLEXPREFIX) --outfile=$(LEXERCPP) $(LEXERSRC)
33+
34+
$(PARSERCPP) $(PARSERHDR): $(PARSERSRC)
35+
bison $(BISONFLAGS) --defines=$(PARSERHDR) --output=$(PARSERCPP) $(PARSERSRC)
36+
37+
counter:
38+
bison -Wcounterexamples $(BISONFLAGS) --defines=$(PARSERHDR) --output=$(PARSERCPP) $(PARSERSRC)
39+
40+
$(LEXERCPP:.cpp=.o): $(LEXERCPP)
41+
$(COMPILER) $(CFLAGS) $(LEXFLAGS) -c $< -o $@
42+
43+
$(PARSERCPP:.cpp=.o): $(PARSERCPP) $(PARSERHDR)
44+
$(COMPILER) $(CFLAGS) $(LEXFLAGS) -c $< -o $@
45+
46+
clean:
47+
rm -f $(LEXERCPP) $(PARSERCPP) $(PARSERHDR) $(OBJECTS) $(OUTPUT) bison.output

include/ASTNode.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#pragma once
2+
3+
#include <initializer_list>
4+
#include <list>
5+
#include <ostream>
6+
#include <string>
7+
8+
struct ASTLocation {
9+
size_t line;
10+
size_t column;
11+
12+
operator std::string() const;
13+
};
14+
15+
std::ostream & operator<<(std::ostream &, const ASTLocation &);
16+
17+
class Parser;
18+
19+
class ASTNode {
20+
private:
21+
ASTNode() {}
22+
23+
public:
24+
Parser *parser;
25+
int symbol;
26+
ASTLocation location;
27+
const std::string *lexerInfo;
28+
ASTNode *parent = nullptr;
29+
std::list<ASTNode *> children;
30+
int debugIndex = -1;
31+
32+
ASTNode(Parser &, int sym, const ASTLocation &loc, const char *info);
33+
ASTNode(Parser &, int sym, const ASTLocation &loc, const std::string *info);
34+
ASTNode(Parser &, int sym, const char *info);
35+
ASTNode(Parser &, int sym, const std::string *info);
36+
ASTNode(Parser &, int sym, const ASTLocation &loc);
37+
ASTNode(Parser &, int sym);
38+
/** Constructs an ASTNode that adopts another node and copies its location. */
39+
ASTNode(Parser &, int sym, ASTNode *, const char *info = "");
40+
ASTNode(Parser &, int sym, ASTNode *, const std::string *info);
41+
virtual ~ASTNode();
42+
43+
ASTNode * operator[](size_t) const;
44+
ASTNode * at(size_t) const;
45+
size_t size() const;
46+
bool empty() const;
47+
ASTNode * adopt(ASTNode *, bool do_locate = false);
48+
ASTNode * adopt(std::initializer_list<ASTNode *>);
49+
ASTNode * absorb(ASTNode *);
50+
ASTNode * clear();
51+
ASTNode * copy() const;
52+
/** Copies the location from another node. */
53+
ASTNode * locate(const ASTNode *);
54+
/** Copies the location from the first node in the list that isn't null. */
55+
ASTNode * locate(std::initializer_list<const ASTNode *>);
56+
ASTNode * locate(const ASTLocation &);
57+
long atoi() const;
58+
long atoi(int offset) const;
59+
const char * getName() const;
60+
void debug(int indent = 0, bool is_last = false, bool suppress_line = false) const;
61+
virtual std::string debugExtra() const;
62+
virtual std::string style() const;
63+
64+
static void destroy(std::initializer_list<ASTNode *>);
65+
66+
ASTNode * front() const;
67+
ASTNode * back() const;
68+
decltype(children)::iterator begin();
69+
decltype(children)::iterator end();
70+
decltype(children)::const_iterator begin() const;
71+
decltype(children)::const_iterator end() const;
72+
decltype(children)::const_iterator cbegin() const noexcept;
73+
decltype(children)::const_iterator cend() const noexcept;
74+
};

include/Lexer.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#pragma once
2+
3+
#include <unordered_map>
4+
#include <vector>
5+
6+
#include <stdio.h>
7+
8+
#include "ASTNode.h"
9+
10+
#define CMMSTYPE_IS_DECLARED
11+
typedef ASTNode * CMMSTYPE;
12+
13+
#ifndef NO_YYPARSE
14+
#include "bison.h"
15+
#endif
16+
17+
#ifdef __APPLE__
18+
typedef size_t yysize;
19+
#else
20+
typedef int yysize;
21+
#endif
22+
23+
extern FILE *cmmin;
24+
extern char *cmmtext;
25+
extern yysize cmmleng;
26+
extern int cmm_flex_debug;
27+
extern int cmmdebug;
28+
29+
class Parser;
30+
31+
class Lexer {
32+
private:
33+
Parser *parser;
34+
yysize *leng;
35+
ASTNode **lval;
36+
37+
public:
38+
ASTLocation location = {0, 1};
39+
std::string line;
40+
yysize lastYylength = 0;
41+
std::unordered_map<int, std::string> lines;
42+
bool failed = false;
43+
std::vector<std::pair<std::string, ASTLocation>> errors;
44+
45+
Lexer(Parser &, yysize &, ASTNode *&);
46+
const std::string * filename(int fileno);
47+
void advance(const char *);
48+
void newline();
49+
void badchar(unsigned char);
50+
int token(const char *, int symbol);
51+
};
52+
53+
extern Lexer cmmLexer;
54+
55+
int cmmlex();
56+
int cmmlex_destroy();
57+
int cmmparse();
58+
void cmmerror(const std::string &);
59+
void cmmerror(const std::string &, const ASTLocation &);

include/Parser.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
#include <cstdio>
4+
#include <string>
5+
6+
#include "ASTNode.h"
7+
8+
typedef struct yy_buffer_state * YY_BUFFER_STATE;
9+
10+
class Parser {
11+
private:
12+
std::string filename;
13+
char *buffer = nullptr;
14+
YY_BUFFER_STATE bufferState = nullptr;
15+
16+
public:
17+
ASTNode *root = nullptr;
18+
int errorCount = 0;
19+
20+
Parser() = default;
21+
void open(const std::string &filename);
22+
void in(const std::string &text);
23+
void debug(bool flex, bool bison);
24+
void parse();
25+
void done();
26+
27+
const char * getName(int symbol);
28+
std::string getBuffer() const;
29+
};
30+
31+
extern Parser cmmParser;

include/StringSet.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <unordered_set>
5+
6+
struct StringSet {
7+
StringSet();
8+
9+
static std::unordered_set<std::string> set;
10+
static const std::string * intern(const char *);
11+
static const std::string * intern(const std::string &);
12+
};

include/Util.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <vector>
5+
6+
namespace Util {
7+
std::vector<std::string> split(const std::string &str, const std::string &delimiter, bool condense = true);
8+
long parseLong(const std::string &, int base = 10);
9+
long parseLong(const std::string *, int base = 10);
10+
long parseLong(const char *, int base = 10);
11+
}

src/Util.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <stdexcept>
2+
3+
#include "Util.h"
4+
5+
namespace Util {
6+
std::vector<std::string> split(const std::string &str, const std::string &delimiter, bool condense) {
7+
if (str.empty())
8+
return {};
9+
10+
size_t next = str.find(delimiter);
11+
if (next == std::string::npos)
12+
return {str};
13+
14+
std::vector<std::string> out {};
15+
const size_t delimiter_length = delimiter.size();
16+
size_t last = 0;
17+
18+
out.push_back(str.substr(0, next));
19+
20+
while (next != std::string::npos) {
21+
last = next;
22+
next = str.find(delimiter, last + delimiter_length);
23+
std::string sub = str.substr(last + delimiter_length, next - last - delimiter_length);
24+
if (!sub.empty() || !condense)
25+
out.push_back(std::move(sub));
26+
}
27+
28+
return out;
29+
}
30+
31+
long parseLong(const std::string &str, int base) {
32+
const char *c_str = str.c_str();
33+
char *end;
34+
long parsed = strtol(c_str, &end, base);
35+
if (c_str + str.length() != end)
36+
throw std::invalid_argument("Not an integer: \"" + str + "\"");
37+
return parsed;
38+
}
39+
40+
long parseLong(const std::string *str, int base) {
41+
return parseLong(*str, base);
42+
}
43+
44+
long parseLong(const char *str, int base) {
45+
return parseLong(std::string(str), base);
46+
}
47+
}

0 commit comments

Comments
 (0)