Cleanup the exprs namespace for the episode 5

This commit is contained in:
Sameer Rahmani 2021-07-30 12:17:41 +01:00
parent e00156b9e7
commit 54b4458a8d
8 changed files with 495 additions and 32 deletions

439
docs/imgs/ast.svg Normal file
View File

@ -0,0 +1,439 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="29cm"
height="10cm"
viewBox="0 0 290 99.999997"
version="1.1"
id="svg8"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
sodipodi:docname="ast.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#2f2f2f"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="763.09643"
inkscape:cy="181.95893"
inkscape:document-units="mm"
inkscape:current-layer="g2389"
inkscape:document-rotation="0"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1064"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
units="cm" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g965"
transform="translate(168.03441,76.711761)" />
<g
id="g2389"
transform="matrix(0.75119316,0,0,0.75119316,51.312464,-32.10995)">
<g
id="g844"
transform="translate(13.040514,28.699914)">
<rect
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.428288;stroke-linejoin:round"
id="rect833"
width="42.223991"
height="17.314972"
x="17.065075"
y="20.493992" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583;fill:#333333;"
x="29.975029"
y="32.850342"
id="text839"><tspan
sodipodi:role="line"
id="tspan837"
x="29.975029"
y="32.850342"
style="stroke-width:0.264583;fill:#333333;">List</tspan></text>
</g>
<g
id="g852"
transform="translate(236.49722,28.699914)">
<rect
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.428288;stroke-linejoin:round"
id="rect846"
width="42.223991"
height="17.314972"
x="17.065075"
y="20.493992" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583"
x="29.975029"
y="32.850342"
id="text850"><tspan
sodipodi:role="line"
id="tspan848"
x="29.975029"
y="32.850342"
style="fill:#1a1a1a;stroke-width:0.264583">List</tspan></text>
</g>
<g
id="g873"
transform="translate(-74.794886,79.485359)">
<rect
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.552882;stroke-linejoin:round"
id="rect854"
width="50.245274"
height="24.248156"
x="17.127373"
y="18.076727" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583;fill:#333333;"
x="24.819334"
y="28.069159"
id="text858"><tspan
sodipodi:role="line"
id="tspan856"
x="24.819334"
y="28.069159"
style="stroke-width:0.264583;fill:#333333;">Symbol</tspan></text>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583;fill:#333333;"
x="34.455421"
y="37.899265"
id="text864"><tspan
sodipodi:role="line"
id="tspan862"
x="34.455421"
y="37.899265"
style="stroke-width:0.264583;fill:#333333;">def</tspan></text>
</g>
<g
id="g885"
transform="translate(-9.428929,79.485359)">
<rect
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.552882;stroke-linejoin:round"
id="rect875"
width="50.245274"
height="24.248156"
x="17.127373"
y="18.076727" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583;fill:#333333;"
x="24.819334"
y="28.069159"
id="text879"><tspan
sodipodi:role="line"
id="tspan877"
x="24.819334"
y="28.069159"
style="stroke-width:0.264583;fill:#333333;">Symbol</tspan></text>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583;fill:#333333;"
x="30.550186"
y="37.899265"
id="text883"><tspan
sodipodi:role="line"
id="tspan881"
x="30.550186"
y="37.899265"
style="stroke-width:0.264583;fill:#333333;">main</tspan></text>
</g>
<g
id="g897"
transform="translate(8.560606,127.35446)">
<rect
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.552882;stroke-linejoin:round"
id="rect887"
width="50.245274"
height="24.248156"
x="17.127373"
y="18.076727" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583"
x="24.819334"
y="28.069159"
id="text891"><tspan
sodipodi:role="line"
id="tspan889"
x="24.819334"
y="28.069159"
style="fill:#333333;stroke-width:0.264583">Symbol</tspan></text>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583"
x="37.482239"
y="37.899265"
id="text895"><tspan
sodipodi:role="line"
id="tspan893"
x="37.482239"
y="37.899265"
style="fill:#1a1a1a;stroke-width:0.264583">fn</tspan></text>
</g>
<g
id="g937"
transform="translate(194.83176,124.58311)">
<rect
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.552882;stroke-linejoin:round"
id="rect927"
width="50.245274"
height="24.248156"
x="-51.96307"
y="20.848083" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583"
x="-44.271111"
y="30.840515"
id="text931"><tspan
sodipodi:role="line"
id="tspan929"
x="-44.271111"
y="30.840515"
style="fill:#1a1a1a;stroke-width:0.264583">Number</tspan></text>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583"
x="-29.835508"
y="40.67062"
id="text935"><tspan
sodipodi:role="line"
id="tspan933"
x="-29.835508"
y="40.67062"
style="fill:#1a1a1a;stroke-width:0.264583">4</tspan></text>
</g>
<rect
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.552882;stroke-linejoin:round"
id="rect955"
width="50.245274"
height="24.248156"
x="17.127373"
y="16.008705"
transform="translate(168.03441,76.71176)" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583"
x="192.85374"
y="102.6676"
id="text959"><tspan
sodipodi:role="line"
id="tspan957"
x="192.85374"
y="102.6676"
style="fill:#1a1a1a;stroke-width:0.264583">Symbol</tspan></text>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583"
x="202.48984"
y="112.49773"
id="text963"><tspan
sodipodi:role="line"
id="tspan961"
x="202.48984"
y="112.49773"
style="fill:#1a1a1a;stroke-width:0.264583">prn</tspan></text>
<g
id="g997"
transform="translate(244.08463,122.05932)">
<rect
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.552882;stroke-linejoin:round"
id="rect987"
width="50.245274"
height="24.248156"
x="17.127373"
y="18.076727" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583"
x="24.819334"
y="28.069159"
id="text991"><tspan
sodipodi:role="line"
id="tspan989"
x="24.819334"
y="28.069159"
style="fill:#1a1a1a;stroke-width:0.264583">Symbol</tspan></text>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583"
x="30.550186"
y="37.899265"
id="text995"><tspan
sodipodi:role="line"
id="tspan993"
x="30.550186"
y="37.899265"
style="fill:#1a1a1a;stroke-width:0.264583">main</tspan></text>
</g>
<g
id="g905"
transform="translate(71.553646,80.534686)">
<rect
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.428288;stroke-linejoin:round"
id="rect899"
width="42.223991"
height="17.314972"
x="17.065075"
y="20.493992" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583;fill:#333333;"
x="29.975029"
y="32.850342"
id="text903"><tspan
sodipodi:role="line"
id="tspan901"
x="29.975029"
y="32.850342"
style="stroke-width:0.264583;fill:#333333;">List</tspan></text>
</g>
<g
id="g925"
transform="translate(71.867786,128.40379)">
<rect
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.428288;stroke-linejoin:round"
id="rect919"
width="42.223991"
height="17.314972"
x="17.065075"
y="20.493992" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583"
x="29.975029"
y="32.850342"
id="text923"><tspan
sodipodi:role="line"
id="tspan921"
x="29.975029"
y="32.850342"
style="fill:#1a1a1a;stroke-width:0.264583">List</tspan></text>
</g>
<g
id="g985"
transform="translate(248.15757,75.693066)">
<rect
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.428288;stroke-linejoin:round"
id="rect979"
width="42.223991"
height="17.314972"
x="17.065075"
y="20.493992" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;stroke-width:0.264583"
x="29.975029"
y="32.850342"
id="text983"><tspan
sodipodi:role="line"
id="tspan981"
x="29.975029"
y="32.850342"
style="fill:#1a1a1a;stroke-width:0.264583">List</tspan></text>
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 37.22751,66.508878 -12.952959,97.562086"
id="path1037"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g844"
inkscape:connection-end="#g873" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 48.144985,66.508878 37.123996,97.562086"
id="path1039"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g844"
inkscape:connection-end="#g885" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 60.990496,66.508878 38.96731,34.519802"
id="path1041"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g844"
inkscape:connection-end="#g905" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 99.074574,118.34365 65.733643,145.43119"
id="path1043"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g905"
inkscape:connection-end="#g897" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 109.78753,118.34365 0.20051,30.55413"
id="path1045"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g905"
inkscape:connection-end="#g925" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 120.26758,118.34365 32.96775,27.08754"
id="path1047"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g905"
inkscape:connection-end="#g937" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 263.31186,66.508878 -37.11531,28.27961"
id="path1057"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g852" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 276.82246,66.508878 7.36401,29.67818"
id="path1059"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g852"
inkscape:connection-end="#g985" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 286.33464,113.50203 v 26.63402"
id="path1067"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g985"
inkscape:connection-end="#g997" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -84,7 +84,8 @@ Deducted from https://www.aosabook.org/en/llvm.html
- Finally we fully lower =lir= to =LLVM IR= and pass it to the object generator
to generate object files.
- Call the default =c compiler= to link the object files and generate the machine code.
* Episode 4 - The reader
* DONE Episode 4 - The reader
CLOSED: [2021-07-27 Tue 22:50]
** What is a Parser ?
To put it simply, Parser converts the source code to an [[https://en.wikipedia.org/wiki/Abstract_syntax_tree][AST]]
*** Algorithms
@ -110,3 +111,21 @@ Read More:
#+END_SRC
- LL(1.5)?
- O(n)
* Episode 5 - The Abstract Syntax Tree
** What is an AST?
Ast is a tree representation of the abstract syntactic structure of source code. It's just a tree made of nodes that each node is
a data structure describing the syntax.
#+BEGIN_SRC lisp
;; pseudo code
(def main (fn () 4))
(prn (main))
#+END_SRC
[[./imgs/ast.svg]]
** The =Expression= abstract class
*** Expressions
- Expressions vs Statements
- Serene(Lisp) and expressions
** Node & AST

View File

@ -44,7 +44,7 @@ class Expression;
using Node = std::shared_ptr<Expression>;
using ErrorPtr = std::shared_ptr<errors::Error>;
// tree? Yupe, Errors can be stackable which makes
// tree? Yupe, Errors can be stackable which makes a vector of them a tree
using ErrorTree = std::vector<ErrorPtr>;
using MaybeNode = Result<Node, ErrorTree>;
@ -53,6 +53,7 @@ using Ast = std::vector<Node>;
using MaybeAst = Result<Ast, ErrorTree>;
static auto EmptyNode = MaybeNode::success(nullptr);
/// The base class of the expressions which provides the common interface for
/// the expressions to implement.
class Expression {
@ -80,6 +81,10 @@ public:
/// \param ctx is the context object of the semantic analyzer.
virtual MaybeNode analyze(SereneContext &ctx) = 0;
/// Genenates the correspondig SLIR of the expressoin and attach it to the
/// module of the given namespace.
///
/// \param ns The namespace that current expression is in it.
virtual void generateIR(serene::Namespace &ns) = 0;
};
@ -97,7 +102,6 @@ template <typename T, typename... Args>
Node make(Args &&...args) {
return std::make_shared<T>(std::forward<Args>(args)...);
};
/// Create a new `node` of type `T` and forwards any given parameter
/// to the constructor of type `T`. This is the **official way** to create
/// a new `Expression`. Here is an example:

View File

@ -28,8 +28,7 @@
#include "serene/context.h"
#include "serene/exprs/expression.h"
#include "llvm/ADT/Optional.h"
#include <llvm/ADT/Optional.h>
#include <string>
namespace serene {
@ -59,21 +58,31 @@ public:
size_t count() const;
Ast from(uint begin);
// llvm::MutableArrayRef<Expression> from(uint begin);
llvm::Optional<Expression *> at(uint index);
/// Return an iterator to be used with the `for` loop. It's implicitly called
/// by the for loop.
std::vector<Node>::const_iterator cbegin();
/// Return an iterator to be used with the `for` loop. It's implicitly called
/// by the for loop.
std::vector<Node>::const_iterator cend();
/// Return an iterator to be used with the `for` loop. It's implicitly called
/// by the for loop.
std::vector<Node>::iterator begin();
/// Return an iterator to be used with the `for` loop. It's implicitly called
/// by the for loop.
std::vector<Node>::iterator end();
MaybeNode analyze(SereneContext &);
void generateIR(serene::Namespace &){};
static bool classof(const Expression *e);
~List() = default;
static bool classof(const Expression *e);
};
} // namespace exprs

View File

@ -29,10 +29,9 @@
#include "serene/exprs/expression.h"
#include "serene/namespace.h"
#include "llvm/Support/FormatVariadic.h"
#include <llvm/Support/FormatVariadic.h>
namespace serene {
namespace exprs {
/// This data structure represent a number. I handles float points, integers,
@ -40,7 +39,8 @@ namespace exprs {
/// So it won't cast to actual numeric types and it has a string container
/// to hold the parsed value.
struct Number : public Expression {
// TODO: Use a variant here instead
// TODO: Use a variant here instead to store different number types
std::string value;
bool isNeg;
@ -52,15 +52,16 @@ struct Number : public Expression {
ExprType getType() const;
std::string toString() const;
MaybeNode analyze(SereneContext &ctx);
static bool classof(const Expression *e);
MaybeNode analyze(SereneContext &ctx);
void generateIR(serene::Namespace &);
// TODO: This is horrible, we need to fix it after the mvp
int toI64();
void generateIR(serene::Namespace &);
~Number() = default;
static bool classof(const Expression *e);
};
} // namespace exprs

View File

@ -28,8 +28,7 @@
#include "serene/context.h"
#include "serene/exprs/expression.h"
#include "llvm/ADT/StringRef.h"
#include <llvm/ADT/StringRef.h>
#include <string>
namespace serene {
@ -51,12 +50,12 @@ public:
ExprType getType() const;
std::string toString() const;
static bool classof(const Expression *e);
MaybeNode analyze(SereneContext &);
void generateIR(serene::Namespace &){};
~Symbol() = default;
static bool classof(const Expression *e);
};
} // namespace exprs

View File

@ -31,11 +31,10 @@
#include "serene/exprs/fn.h"
#include "serene/exprs/symbol.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"
#include <iterator>
#include <llvm/Support/Casting.h>
#include <llvm/Support/ErrorHandling.h>
#include <llvm/Support/FormatVariadic.h>
namespace serene {
namespace exprs {
@ -91,20 +90,12 @@ bool List::classof(const Expression *e) {
return e->getType() == ExprType::List;
};
/// Return an iterator to be used with the `for` loop. It's implicitly called by
/// the for loop.
std::vector<Node>::const_iterator List::cbegin() { return elements.begin(); }
/// Return an iterator to be used with the `for` loop. It's implicitly called by
/// the for loop.
std::vector<Node>::const_iterator List::cend() { return elements.end(); }
/// Return an iterator to be used with the `for` loop. It's implicitly called by
/// the for loop.
std::vector<Node>::iterator List::begin() { return elements.begin(); }
/// Return an iterator to be used with the `for` loop. It's implicitly called by
/// the for loop.
std::vector<Node>::iterator List::end() { return elements.end(); }
size_t List::count() const { return elements.size(); }
@ -118,7 +109,6 @@ llvm::Optional<Expression *> List::at(uint index) {
}
Ast List::from(uint index) {
if (index < elements.size()) {
return Ast(elements.begin() + index, elements.end());
}

View File

@ -24,7 +24,9 @@
#include "serene/exprs/symbol.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Casting.h"
#include <llvm/Support/FormatVariadic.h>
namespace serene {
namespace exprs {