Prepare tho source tree for episode number 6

This commit is contained in:
Sameer Rahmani 2021-08-07 17:41:19 +01:00
parent 54b4458a8d
commit 32b406fdad
11 changed files with 522 additions and 20 deletions

View File

@ -69,6 +69,8 @@ enum Action {
DumpIR,
CompileToObject,
Compile,
// TODO: Remove this option and replace it by a subcommand
JIT,
};
}
@ -99,7 +101,8 @@ static cl::opt<enum Action> emitAction(
cl::values(clEnumValN(CompileToObject, "object",
"Compile to object file.")),
cl::values(clEnumValN(Compile, "target",
"Compile to target code. (Default)"))
"Compile to target code. (Default)")),
cl::values(clEnumValN(JIT, "jit", "Run the give input file with the JIT."))
);
@ -243,6 +246,10 @@ int main(int argc, char *argv[]) {
switch (emitAction) {
case Action::JIT: {
break;
};
// Just print out the raw AST
case Action::DumpAST: {
auto ast = readInputFile();
@ -303,6 +310,8 @@ int main(int argc, char *argv[]) {
}
if (emitAction < CompileToObject) {
serene::slir::dump<Namespace>(*ns);
} else if (emitAction == Action::JIT) {
} else {
return dumpAsObject(*ns);
}

View File

@ -0,0 +1,167 @@
<?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="16cm"
height="10cm"
viewBox="0 0 160 99.999997"
version="1.1"
id="svg8"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
sodipodi:docname="incorrct_semantic.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="331.15811"
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(0.0122228,25.177739)">
<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;fill:#333333;stroke-width:0.264583"
x="29.975029"
y="32.850342"
id="text839"><tspan
sodipodi:role="line"
id="tspan837"
x="29.975029"
y="32.850342"
style="fill:#333333;stroke-width:0.264583">List</tspan></text>
</g>
<g
id="g873"
transform="translate(-74.794886,75.963184)">
<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="19.014702" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:Charter;-inkscape-font-specification:Charter;fill:#333333;stroke-width:0.264583"
x="24.819334"
y="28.069159"
id="text858"><tspan
sodipodi:role="line"
id="tspan856"
x="24.819334"
y="28.069159"
style="fill:#333333;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;fill:#333333;stroke-width:0.264583"
x="39.254936"
y="37.899265"
id="text864"><tspan
sodipodi:role="line"
id="tspan862"
x="39.254936"
y="37.899265"
style="fill:#333333;stroke-width:0.264583">4</tspan></text>
</g>
<g
id="g885"
transform="translate(66.698034,76.901159)">
<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;fill:#333333;stroke-width:0.264583"
x="24.819334"
y="28.069159"
id="text879"><tspan
sodipodi:role="line"
id="tspan877"
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;fill:#333333;stroke-width:0.264583"
x="30.550186"
y="37.899265"
id="text883"><tspan
sodipodi:role="line"
id="tspan881"
x="30.550186"
y="37.899265"
style="fill:#333333;stroke-width:0.264583">main</tspan></text>
</g>
<path
style="fill:#ffffff;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.352217px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M -15.350126,94.977886 27.529389,62.986703"
id="path922"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g873"
inkscape:connection-end="#g844" />
<path
style="fill:#ffffff;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.352217px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 48.852903,62.986703 91.747318,94.977886"
id="path924"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g844"
inkscape:connection-end="#g885" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

251
docs/imgs/semantic.svg Normal file
View File

@ -0,0 +1,251 @@
<?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="922.8819"
height="235.56693"
viewBox="0 0 244.17924 62.327093"
version="1.1"
id="svg8"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
sodipodi:docname="semantic.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="565.58705"
inkscape:cy="393.87544"
inkscape:document-units="mm"
inkscape:current-layer="g905"
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="px"
scale-x="1" />
<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(-3.0341942,27.472385)">
<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;fill:#333333;stroke-width:0.264583"
x="29.975029"
y="32.850342"
id="text839"><tspan
sodipodi:role="line"
id="tspan837"
x="29.975029"
y="32.850342"
style="fill:#333333;stroke-width:0.264583">Def</tspan></text>
</g>
<g
id="g852"
transform="translate(155.69059,28.20857)">
<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">Call</tspan></text>
</g>
<g
id="g885"
transform="translate(-78.928215,77.877707)">
<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;fill:#333333;stroke-width:0.264583"
x="24.819334"
y="28.069159"
id="text879"><tspan
sodipodi:role="line"
id="tspan877"
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;fill:#333333;stroke-width:0.264583"
x="30.550186"
y="37.899265"
id="text883"><tspan
sodipodi:role="line"
id="tspan881"
x="30.550186"
y="37.899265"
style="fill:#333333;stroke-width:0.264583">main</tspan></text>
</g>
<g
id="g1187"
transform="translate(-57.763668,4.4614976)">
<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>
<g
id="g905"
transform="translate(55.478938,78.927034)">
<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;fill:#333333;stroke-width:0.264583"
x="32.287472"
y="32.850342"
id="text903"><tspan
sodipodi:role="line"
id="tspan901"
x="32.287472"
y="32.850342"
style="fill:#333333;stroke-width:0.264583">Fn</tspan></text>
</g>
<g
id="g985"
transform="translate(190.39431,80.154563)">
<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 23.058642,65.281349 -19.755257,95.954434"
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 44.987986,65.281349 83.8109,99.421026"
id="path1041"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g844"
inkscape:connection-end="#g905" />
<path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 187.68108,66.017534 162.87546,97.181963"
id="path1057"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g852"
inkscape:connection-end="#g1187" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 200.35592,66.017534 23.13606,34.631016"
id="path1059"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-end="#g985"
inkscape:connection-start="#g852" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -111,7 +111,8 @@ Read More:
#+END_SRC
- LL(1.5)?
- O(n)
* Episode 5 - The Abstract Syntax Tree
* DONE Episode 5 - The Abstract Syntax Tree
CLOSED: [2021-07-30 Fri 14:01]
** 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.
@ -129,3 +130,31 @@ a data structure describing the syntax.
- Expressions vs Statements
- Serene(Lisp) and expressions
** Node & AST
* Episode 6 - The Semantic Analyzer
** Qs
- Why didn't we implement a linked list?
- Why we are using the =std::vector= instead of llvm collections?
** What is Semantic Analysis?
- Semantic Analysis makes sure that the given program is semantically correct.
- Type checkr works as part of this step as well.
#+BEGIN_SRC lisp
;; pseudo code
(4 main)
#+END_SRC
[[./imgs/incorrct_semantic.svg]]
** Semantic Analysis and rewrites
We need to reform the AST to reflect the semantics of Serene closly.
#+BEGIN_SRC lisp
;; pseudo code
(def main (fn () 4))
(prn (main))
#+END_SRC
[[./imgs/ast.svg]]
[[./imgs/semantic.svg]]
Let's run the compiler to see the semantic analysis in action.
** Let's check out the code

View File

@ -40,8 +40,8 @@ namespace serene {
namespace exprs {
class List;
/// This data structure represent the Lisp symbol. Just a symbol
/// in the context of the AST and nothing else.
/// This data structure represents the operation to define a new binding via
/// the `def` special form.
class Def : public Expression {
public:

44
include/serene/jit.h Normal file
View File

@ -0,0 +1,44 @@
/* -*- C++ -*-
* Serene programming language.
*
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef SERENE_JIT_H
#define SERENE_JIT_H
#include "serene/slir/generatable.h"
#include "llvm/ADT/StringRef.h"
#include <memory>
#include <mlir/ExecutionEngine/ExecutionEngine.h>
namespace serene {
class JIT {
std::unique_ptr<mlir::ExecutionEngine> engine;
public:
JIT(SereneContext &c, Namespace &entryNS, llvm::StringRef fn = "main") {}
};
} // namespace serene
#endif

View File

@ -31,12 +31,18 @@
namespace serene::reader {
using AnalyzeResult = Result<exprs::Ast, std::vector<exprs::ErrorPtr>>;
/// This function is the entrypoint to the Semantic Analysis phase of **Serene**
/// It will call the `analyze` method on every node in the given AST and
/// returns a new AST as the result of the semantic analysis.
/// The entry point to the Semantic analysis phase. It calls the `analyze`
/// method of each node in the given AST and creates a new AST that contains a
/// more comprehensive set of nodes in a semantically correct AST. If the
/// `analyze` method of a node return a `nullptr` value as the `success` result
/// (Checkout the `Result` type in `utils.h`) then the original node will be
/// used instead. Also please note that in **Serene** Semantic errors
/// represented as AST nodes as well. So you should expect an `analyze` method
/// of a node to return a `Result<node>::Success(Error...)` in case of a
/// semantic error.
///
/// \param ctx The serene context
/// \prama tree The raw AST to analyze
/// \param ctx The semantic analysis context
/// \param inputAst The raw AST to analyze and possibly rewrite.
AnalyzeResult analyze(serene::SereneContext &ctx, exprs::Ast &tree);
}; // namespace serene::reader

View File

@ -52,6 +52,7 @@ bool Call::classof(const Expression *e) {
};
MaybeNode Call::make(SereneContext &ctx, List *list) {
// TODO: replace this with a runtime check
assert((list->count() != 0) && "Empty call? Seriously ?");
// Let's find out what is the first element of the list

View File

@ -111,6 +111,7 @@ MaybeNode Def::make(SereneContext &ctx, List *list) {
llvm_unreachable("Inserting a value in the semantic env failed!");
}
};
void Def::generateIR(serene::Namespace &ns) {
auto &module = ns.getModule();

View File

@ -71,6 +71,8 @@ MaybeNode Fn::make(SereneContext &ctx, List *list) {
}
Symbol *fnSym = llvm::dyn_cast<Symbol>(list->elements[0].get());
// TODO: Replace this assert with a runtime check
assert((fnSym && fnSym->name == "fn") &&
"The first element of the list should be a 'fn'.");
@ -80,12 +82,15 @@ MaybeNode Fn::make(SereneContext &ctx, List *list) {
std::string msg =
llvm::formatv("Arguments of a function has to be a list, got '{0}'",
stringifyExprType(list->elements[1]->getType()));
return makeErrorful<Node>(list->elements[1]->location,
&errors::FnArgsMustBeList, msg);
}
Ast body;
// If there is a body for this function analyze the body and set
// the retuned ast as the final body
if (list->count() > 2) {
body = std::vector<Node>(list->begin() + 2, list->end());
auto maybeAst = reader::analyze(ctx, body);

View File

@ -29,17 +29,6 @@
namespace serene::reader {
/// The entry point to the Semantic analysis phase. It calls the `analyze`
/// method of each node in the given AST and creates a new AST that contains a
/// more comprehensive set of nodes in a semantically correct AST. If the
/// `analyze` method of a node return a `nullptr` value as the `success` result
/// (Checkout the `Result` type in `utils.h`) then the original node will be
/// used instead. Also please note that in **Serene** Semantic errors
/// represented as AST nodes as well. So you should expect an `analyze` method
/// of a node to return a `Result<node>::Success(Error...)` in case of a
/// semantic error.
/// \param ctx The semantic analysis context
/// \param inputAst The raw AST to analyze and possibly rewrite.
AnalyzeResult analyze(serene::SereneContext &ctx, exprs::Ast &inputAst) {
// TODO: Fetch the current namespace from the JIT engine later and if it is
// `nil` then the given `ast` has to start with a namespace definition.