<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Amr Hesham on Medium]]></title>
        <description><![CDATA[Stories by Amr Hesham on Medium]]></description>
        <link>https://medium.com/@amrdeveloper?source=rss-d6ca14e19099------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*U14s7Y-ZewcfbdZBEES51Q.jpeg</url>
            <title>Stories by Amr Hesham on Medium</title>
            <link>https://medium.com/@amrdeveloper?source=rss-d6ca14e19099------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 08 Apr 2026 14:16:57 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@amrdeveloper/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[How I built a LLVM IR linter using SQL syntax]]></title>
            <link>https://itnext.io/how-i-built-a-llvm-ir-linter-using-sql-syntax-b5dc164c6d61?source=rss-d6ca14e19099------2</link>
            <guid isPermaLink="false">https://medium.com/p/b5dc164c6d61</guid>
            <category><![CDATA[gitql]]></category>
            <category><![CDATA[llvm]]></category>
            <category><![CDATA[optimization]]></category>
            <category><![CDATA[linter]]></category>
            <category><![CDATA[compilers]]></category>
            <dc:creator><![CDATA[Amr Hesham]]></dc:creator>
            <pubDate>Mon, 10 Feb 2025 00:15:30 GMT</pubDate>
            <atom:updated>2025-02-10T00:15:30.495Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OopCzIn7K5w5trEyex7P4Q.png" /></figure><p>Hello everyone, I am Amr Hesham, a software engineer interested in Open source, Compilers and Language design. In the previous article, I explained how I built an <a href="https://github.com/AmrDeveloper/LLQL"><strong>LLQL</strong></a> tool to search for patterns in LLVM IR/BC files with API similar to LLVM Inst Combine matches functions.</p><p>For example, this query searches for Add with Sub as the left-hand side and Mul as the right-hand side.</p><pre>SELECT instruction FROM instructions WHERE m_inst(instruction, m_add(m_sub(), m_mul()))</pre><p>This query will match the following instruction</p><pre>%sub = sub i32 %a, %b<br>%mull = mul i32 %a, %b<br>%add = add i32 %sub, %mull  &lt;------- Matches</pre><p>Currently, with the improvements of GitQL SDK to support new features in the language, functions and SDK customizations we can take LLQL idea to the next step.</p><p>The idea is that we want to create a linter that detects patterns in the IR/BC that must be optimized, so if they exist in the output IR that means the optimizer missed it,</p><p>GitQL already supports script mode, so you can put all queries in one file and execute it, so you can check for all patterns you want in one run, Let&#39;s start,</p><h4>Create the linter file that will contain all queries</h4><p>So first, let&#39;s create a simple file Lint.sql to add queries for all patterns we want, and we can easily run it using llql -f &quot;Output.ll&quot; -s &quot;Lint.sql .</p><h4>Creating SQL queries for linting</h4><p>So for this article, I will show you how to build queries to detect actual real-case patterns (All patterns in this article are coming from LLVM InstCombine) but you can build the patterns you want using a large set of functions supported in LLQL, you can check them from the <a href="https://amrdeveloper.github.io/LLQL/"><strong>documentation</strong></a><strong>.</strong></p><h4>Pattern 1:</h4><p>The first pattern we want to detect is trunc(binop(Y, ext(X)) because it can be optimized tobinop(trunc(y), x), note that binop here means that it can match BinaryExpression for example Add, Sub, Mul, Or, And …etc, ext mean zext (zero-extends an integer to a larger size) or sext (sign extension on integer values) and trunc for truncate.</p><p>We can count the number of times this pattern appears or print the instructions or something else, for me, I would like to print the instructions so the query will be like</p><pre>SELECT instruction AS &quot;Missing Optimization: trunc (binop (Y, (ext X))) --&gt; binop ((trunc Y), X)&quot;<br>FROM instructions WHERE m_inst(instruction, m_trunc(m_binop(m_any_inst(), m_zext() || m_sext())));</pre><p>You can realize that we almost wrote the same pattern but with m_ as prefix and m_zext() || m_sext for ext but in future, we can add m_ext .</p><p>If you run this query on a simple example like</p><pre>define i32 @function(i8* %x, i32* %y) { <br>entry: <br>  %load_x = load i8, ptr %x, align 1 <br>  %load_y = load i32, ptr %y, align 4 <br>  %ext_X = zext i8 %load_x to i32 <br>  %add_result = add i32 %load_y, %ext_X <br>  %trunc_result = trunc i32 %add_result to i16 <br>  %ret = zext i16 %trunc_result to i32 <br>  ret i32 %ret <br>}</pre><p>The result will be</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2MGnG8Eou8mUMRgg9ifF0Q.png" /></figure><p>And that is exactly what we want 😋</p><h4>Pattern 2:</h4><p>For the current and next patterns, I will explain only new functions that have not been explained before 😉, so our next pattern to detect is trunc(binop(ext(X), Y)) that can be optimized to binop(X, trunc(Y)) , it’s very similar to the previous pattern the only difference is that the operand of binop seems to be reversed, and in this case, we can detect it in two ways depending on what output we want to get.</p><p>The first way is to create a new query to detect this pattern and append it to our lint file</p><pre>SELECT instruction AS &quot;Missing Optimization: trunc (binop (ext X), Y) --&gt; binop (X, (trunc Y))&quot;<br>FROM instructions WHERE m_inst(instruction, m_trunc(m_binop(m_zext() || m_sext())));</pre><p>So we can get a specific title for each pattern, but what if we don’t care about the title, then we can replace m_binop with m_c_binop which means commutatively_binop, Basically, it matches the binop without caring about the order of operands, Which means we can detect both patterns in one query 🤯.</p><p><strong>Pattern 3:</strong></p><p>In this pattern, what we want is to check for missing constants folding optimizations for example, if there is something like add 2, 4 because we can easily replace it by 6 at compile time, the query here is much easier because we have a matcher for constants value so it will be like</p><pre>-- Constant folding<br>SELECT instruction AS &quot;Missing Optimization: Constants folding&quot;<br>FROM instructions WHERE m_inst(instruction, m_binop(m_const_int(), m_const_int()));</pre><p>That means we check for binary expressions with both left and right sides constants int values.</p><p>I hope you enjoyed the article and samples, there are tons of matchers supported in LLQL and the end goal is to support all matchers in the upstream LLVM pattern matchers.</p><p>Feel free to join the project as a contributor. There is room for everyone 😉</p><p><a href="https://github.com/AmrDeveloper/LLQL">GitHub - AmrDeveloper/LLQL: LLQL is a tool that allow you to run SQL-like query with Pattern matching functions inspired by LLVM InstCombine Pattern Matchers on LLVM IR/Bitcode files</a></p><p>I am looking forward to your opinion and feedback 😋.</p><p>I hope you enjoyed my article and you can find me on</p><p>You can find me on: <a href="https://github.com/amrdeveloper"><strong>GitHub</strong></a>, <a href="https://www.linkedin.com/in/amrdeveloper/"><strong>LinkedIn</strong></a>, and <a href="https://twitter.com/amrdeveloper"><strong>Twitter</strong></a>.</p><p>Enjoy Programming 😋.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b5dc164c6d61" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/how-i-built-a-llvm-ir-linter-using-sql-syntax-b5dc164c6d61">How I built a LLVM IR linter using SQL syntax</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[LLQL: Matching patterns in LLVM IR/BC files using SQL query]]></title>
            <link>https://amrdeveloper.medium.com/llql-matching-patterns-in-llvm-ir-bc-files-using-sql-query-ef47040580d9?source=rss-d6ca14e19099------2</link>
            <guid isPermaLink="false">https://medium.com/p/ef47040580d9</guid>
            <category><![CDATA[gitql]]></category>
            <category><![CDATA[llvm]]></category>
            <category><![CDATA[irs]]></category>
            <category><![CDATA[llql]]></category>
            <category><![CDATA[sql]]></category>
            <dc:creator><![CDATA[Amr Hesham]]></dc:creator>
            <pubDate>Thu, 31 Oct 2024 19:18:32 GMT</pubDate>
            <atom:updated>2024-10-31T19:18:32.530Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*chLb8Q8exZZUtrtLWAxpiA.png" /></figure><p>Hello everyone, in the last two months i started to contribute to the LLVM amazing project (You can find my patches <a href="https://github.com/llvm/llvm-project/commits?author=AmrDeveloper"><strong>here</strong></a>) and in this interesting <a href="https://github.com/llvm/llvm-project/commit/9614f69b4b1ebaba7a8ad51d583844ebca99bb08"><strong>patch</strong></a><strong> </strong>the goal was to match pattern in the LLVM IR and transform it to more optimized form, to do this work i got a recommendation from a LLVM organization member to look at the InstCombine Guide for contributor which can be found <a href="https://llvm.org/docs/InstCombineContributorGuide.html"><strong>here</strong></a>, and i found that LLVM has a very interesting pattern matching functions to match the pattern you want, for example if you want to search for pattern like this (A — B) + B you can write</p><pre>Value *A, *B;<br>if (match(V, m_Add(m_Sub(m_Value(A), m_Value(B)), m_Deferred(B)))) {<br>}</pre><p>And if you want to search for. (A-B) + B or B + (A — B) you can replace m_add with m_c_add , the extra C is for commutatively.</p><pre>Value *A, *B;<br>if (match(V, m_c_Add(m_Sub(m_Value(A), m_Value(B)), m_Deferred(B)))) {<br>}</pre><p>I finished the patch and it’s merged 🥳🥳, and i back to work on <a href="https://github.com/AmrDeveloper/GQL"><strong>GitQL</strong></a> query engine, at this time i have created the <a href="https://github.com/AmrDeveloper/ClangQL"><strong>ClangQL</strong></a> tool which is used to run SQL query on your C/C++ code, and i got one question in my mind, What if i can run SQL query on LLVM IR and be able to perform pattern matching like in InstCombine part 🤔🤔.</p><h3>The LLQL Project</h3><p>At the start i was thinking okey, how to represent the information like instructions, and how to make performing pattern matching smooth like in LLVM, also how to provide a clean error message and maybe in the future support operators for those new types.</p><h4>Representing the LLVM Types and Values</h4><p>What i want here is to have types that map to LLVM types like like i8 , i32 , pointers , arrays , or vectors…etc, and work with them as if they are primitives in GitQL Query Engine.</p><p>Thanks to the GitQL new architecture which allow SDK user to define his own types, values and functions (You can read the full details about the design from this article <a href="https://medium.com/@amrdeveloper/gitql-the-data-types-from-the-engine-to-the-sdk-5c48d9c60945"><strong>GitQL: The data types from the Engine to the SDK</strong></a>), i started to create Types to be as wrapper for LLVM values for example LLVMDataType which represent Types in LLVM, and created a value that represent that type</p><pre>pub struct LLVMTypeValue {<br>    pub llvm_type: LLVMTypeRef,<br>}<br><br>impl Value for LLVMTypeValue {<br>    ...<br><br>    fn data_type(&amp;self) -&gt; Box&lt;dyn DataType&gt; {<br>        Box::new(LLVMDataType)<br>    }<br>}</pre><p>and the same idea to represent the LLVMValueRef the code is like this</p><pre>pub struct ≈ {<br>    pub llvm_type: LLVMTypeRef,<br>}<br><br>impl Value for LLVMTypeValue {<br>   ...<br><br>   fn data_type(&amp;self) -&gt; Box&lt;dyn DataType&gt; {<br>        Box::new(LLVMDataType)<br>    }<br>}</pre><p>After creating the Schema and DataProvider i can select instructions from IR files like this</p><pre>SELECT instruction FROM instructions</pre><p>and got a result like this</p><pre>│ instruction                      │<br>╞══════════════════════════════════╡<br>│   %sub = sub i32 %a, %b          │<br>├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤<br>│   %mull = mul i32 %a, %b         │<br>├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤<br>│   %add = add i32 %sub, %mull     │<br>├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤<br>│   ret i32 %add                   │<br>├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤<br>│   %result = add i32 %a, 0        │<br>├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤</pre><p>Now it’s time to find a way to perform pattern matching 🤔.</p><h4>Building the Pattern Matcher</h4><p>What i want is to be able to perform query like this</p><pre>SELECT instruction FROM instructions WHERE m_inst(instruction, m_add(m_sub(), m_mul()))</pre><p>This match for Add instruction that as Sub Instruction as Left hand side and Mul instruction as right hand side, in LLVM IR it can be like this</p><pre>%sub = sub i32 %a, %b<br>%mull = mul i32 %a, %b<br>%add = add i32 %sub, %mull  &lt;------- Like this add</pre><p>`So my idea was that lets think of this Add as Node that has two children, each one of them is another node, so what i want is to have a tree structure of Patterns that each node can be matched or not againts that same node in the real IR tree,</p><p>So i created a new Type that represent the Matchers so i can make sure that user can only pass the correct type to my new matchers, I called it InstMatcherType for Instruction Matchers and TypeMatcherType for data types matchers, then created a values for them and also a Matchers functions so what the functions does is to build and connect the nodes to endup with full pattern and m_inst will match, so the Matcher node is like</p><pre>pub trait InstMatcher: DynClone {<br>    fn is_match(&amp;self, instruction: LLVMValueRef) -&gt; bool;<br>}</pre><p>And now i can create BinaryMatchers that can match his two childrens too, or UnaryMatchers, …etc</p><p>The first function i created as m_inst which take Instruction and Pattern and return true if the instruction is matched with the pattern, and now i created the m_add function which take optional two other InstMatchers for Left and Right sides, so the implementation is like this</p><pre>fn match_add_inst(values: &amp;[Box&lt;dyn Value&gt;]) -&gt; Box&lt;dyn Value&gt; {<br>    let (lhs_matcher, rhs_matcher) = binary_matchers_sides(values);<br>    let matcher = ArithmeticInstMatcher::create_add(lhs_matcher, rhs_matcher);<br>    Box::new(InstMatcherValue { matcher })<br>}<br><br>fn match_sub_inst(values: &amp;[Box&lt;dyn Value&gt;]) -&gt; Box&lt;dyn Value&gt; {<br>    let (lhs_matcher, rhs_matcher) = binary_matchers_sides(values);<br>    let matcher = ArithmeticInstMatcher::create_sub(lhs_matcher, rhs_matcher);<br>    Box::new(InstMatcherValue { matcher })<br>}<br><br>fn match_mul_inst(values: &amp;[Box&lt;dyn Value&gt;]) -&gt; Box&lt;dyn Value&gt; {<br>    let (lhs_matcher, rhs_matcher) = binary_matchers_sides(values);<br>    let matcher = ArithmeticInstMatcher::create_mul(lhs_matcher, rhs_matcher);<br>    Box::new(InstMatcherValue { matcher })<br>}</pre><p>and the signature is like</p><pre>Signature {<br>    parameters: vec![<br>        Box::new(OptionType {<br>            base: Some(Box::new(InstMatcherType)),<br>        }),<br>        Box::new(OptionType {<br>             base: Some(Box::new(InstMatcherType)),<br>        }),<br>     ],<br>     return_type: Box::new(InstMatcherType),<br>}</pre><p>Thats mean we can call it with 0 arguments to match any Add Instructions, for example</p><pre>SELECT instruction FROM instructions WHERE m_inst(instruction, m_add())</pre><p>Or with arguments to match add and then match childrens too</p><pre>SELECT instruction FROM instructions WHERE m_inst(instruction, m_add(m_sub(), m_mul()))</pre><p>You can query how many times this pattern exists in each function</p><pre>SELECT function_name, count() FROM instructions WHERE m_inst(instruction, m_add(m_sub(), m_mul())) GROUP BY function_name</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3ZFIOqEpFWvfOuJOpJuUUg.png" /></figure><p>And now you can perform pattern matching againts LLVM IR or BC Instructions.</p><h3><strong>What is next!</strong></h3><p>The current state is that you can build your pattern with matchers for Arithmetic, ICMP and FCMP matchers, and there are a lot of other matchers that we can support and we can perform more deep analysis, feel free to write feedback, report issues or fix bugs, everyone is most welcome.</p><p>The project is free and open source, you can find <a href="https://github.com/AmrDeveloper/LLQL"><strong>The LLQL repository on Github</strong></a><strong> </strong>and don’t forget to give it a star 🌟</p><p>I am looking forward to your opinion and feedback 😋.</p><p>I hope you enjoyed my article and you can find me on</p><p>You can find me on: <a href="https://github.com/amrdeveloper"><strong>GitHub</strong></a>, <a href="https://www.linkedin.com/in/amrdeveloper/"><strong>LinkedIn</strong></a>, and <a href="https://twitter.com/amrdeveloper"><strong>Twitter</strong></a>.</p><p>Enjoy Programming 😋.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ef47040580d9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GitQL: The data types from the Engine to the SDK]]></title>
            <link>https://amrdeveloper.medium.com/gitql-the-data-types-from-the-engine-to-the-sdk-5c48d9c60945?source=rss-d6ca14e19099------2</link>
            <guid isPermaLink="false">https://medium.com/p/5c48d9c60945</guid>
            <category><![CDATA[gitql]]></category>
            <category><![CDATA[git]]></category>
            <category><![CDATA[design]]></category>
            <category><![CDATA[rust]]></category>
            <category><![CDATA[database]]></category>
            <dc:creator><![CDATA[Amr Hesham]]></dc:creator>
            <pubDate>Thu, 31 Oct 2024 19:18:29 GMT</pubDate>
            <atom:updated>2024-10-31T19:18:29.043Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Qz_yed5u0hfKsHZp-3ISJw.png" /></figure><p>Hello everyone, in the last few months, the <a href="https://github.com/AmrDeveloper/GQL"><strong>GitQL</strong></a> project has become bigger and has a lot of useful features now some tools are built using the SDK, like <a href="https://github.com/AmrDeveloper/FileQL"><strong>FileQL</strong></a> and <a href="https://github.com/AmrDeveloper/ClangQL"><strong>ClangQL</strong></a>,<strong> so </strong>we have reached the point where we can query any kind of data by defining the Data Schema and Provider and map the data to the GitQL builtin types like Integer, Text, Date, Array …etc. and also can extend the Std library to defining your custom functions, but what if you want to create a new custom data type 🤔🤔🤔! And why do you need a custom type?</p><h4>The benefit of having custom data types</h4><p>Imagine you want to create a tool to run SQL queries on matrix vectors. By default, you can’t write a query like this without supporting the type Matrix in the Engine.</p><pre>SELECT matrix1 * matrix2;</pre><p>Or, when creating a function that does some calculation on the matrix, what parameter will you use?</p><pre>SELECT perform_on_matrix(matrix1);</pre><p>Maybe you think, okay, let’s make the function take Text as a parameter, and we can convert the matrix to a String and pass it. The function constructs the matrix, does the calculation, and returns it as a string again, but what if the end-user passes any string to the function 🤔.</p><pre>SELECT perform_on_matrix(&quot;Hello, World!&quot;);</pre><p>In this case, if you have a type called Matrix, you can easily make sure that the user can only pass a value with Matrix type, or he will get an error message that Function {} expects the type Matrix but got Text. And if there is a way to do operator overloading, you can support using the + operator between two Matrices.</p><p>In Programming languages, you can create your custom type using Struct or Class to define the structure, and in some languages like C++, you can overload operators for it, too, but how can we get the same result in GitQL using SQL? How can we create a type that can represent complex values like Audio files, Images, Tree data structure of specific values …etc?</p><p>In some Database engines like PostgreSQL, it allows the user to define a type as a composed of other defined types and overload operators with implementation for this type using SQL, but the goal of GitQL SDK is to help you easily build your domain-specific query engine, but what I want here is to be able also to define new types that maybe not composed from primitives like Audio, Video, Image, Abstract Syntax Tree for one Language or even Assembly Instruction as Type, but how 🤔.</p><p>So inspired by <a href="https://www.nondot.org/sabre/"><strong>Chris Lattner</strong></a>&#39;s design in Swift and currently in Mojo to move all types, even primitives, from Compiler to be defined in the Standard library, I found that this idea is very good, and if I can implement it in the GitQL to move the types to SDK, any SDK user can easily use interface to define custom types and overload operators for it.</p><h4>Moving the Types from Engine to SDK</h4><p>So what I did is I moved the old Types from the Engine level to the SDK level, so now the Parser, TypeChecker and Engine deal with Abstract Type as interface and don’t know what this type represents, but they know what this type can do, for example, if I want this type to work this * operator I can do this</p><pre>impl DataType for MatrixType {<br>    fn can_perform_mul_op_with(&amp;self) -&gt; Vec&lt;Box&lt;dyn DataType&gt;&gt; {<br>        vec![Box::new(MatrixType)]<br>    }<br><br>    fn mul_op_result_type(&amp;self, _other: &amp;Box&lt;dyn DataType&gt;) -&gt; Box&lt;dyn DataType&gt; {<br>        Box::new(MatrixType)<br>    }<br>}</pre><p>This means that you can perform the * operator between two Matrices, and the second function defines that the expected type from this operation will be MatrixType, there are similar functions for each operator.</p><p>Now then, the parser and type checker find an expression like matrix1 * matrix2, they will call can_perform_mul_op_with to check if this operation is valid or not, and if valid, they will call mul_op_result_type to get the result type from this operation.</p><p>Similar to a custom type, we can define custom Values too, for example</p><pre>pub struct MatrixValue {<br>   pub matrix: Matrix<br>}<br><br>impl Value for MatrixValue {<br>    fn mul_op(&amp;self, other: &amp;Box&lt;dyn Value&gt;) -&gt; Result&lt;Box&lt;dyn Value&gt;, String&gt; {<br>        if let Some(other_matrix) = other.as_any().downcast_ref::&lt;MatrixValue&gt;() {<br>            let value = self.matrix.multiply(other_matrix.matrix);<br>            return Ok(Box::new(MatrixValue { value }));<br>        }<br>        Err(&quot;Unexpected type to perform `*` with&quot;.to_string())<br>    }<br>}</pre><p>Now you can create custom functions that take MatrixType as a parameter or return type to end up with a query like this</p><pre>SELECT create_matrix([1, 2], [3, 4]) * create_matrix([4, 5], [7, 8])</pre><p>With this new architecture, I built a new tool called LLQL, which allows users to run SQL queries on LLVM IR or Bitcode and it’s possible to implement the same idea on Java Byte code, Assembly or even Machine code, here a real example from LLQL readme,</p><p>Imagine we want to search if there is an Add instruction that has sub instruction as left hand side and mul instruction as right hand side</p><pre>define i32 @function(i32 %a, i32 %b) {<br>  %sub = sub i32 %a, %b<br>  %mull = mul i32 %a, %b<br>  %add = add i32 %sub, %mull    &lt;----- Like this Add(Sub, Mul)<br>  ret i32 %add<br>}</pre><p>You can easily search for this pattern using this SQL query</p><pre>SELECT instruction FROM instructions WHERE m_inst(instruction, m_add(m_sub(), m_mul()))</pre><p>In that project Instruction column has InstructionType, m_add, m_sub, m_mul return IntMatcherType and both of them are custom defined type using the SDK without modifying the GitQL engine itself.</p><p>You can read more about LLQL design and implementation from this article: <a href="https://medium.com/@amrdeveloper/llql-matching-patterns-in-llvm-ir-bc-files-using-sql-query-ef47040580d9"><strong>LLQL: Matching patterns in LLVM IR/BC files using SQL query</strong></a></p><p>You can find the full detailed documentation on <a href="https://amrdeveloper.github.io/GQL/"><strong>GitQL website</strong></a><strong>.</strong></p><p>I am looking forward to your opinion and feedback 😋.</p><p>I hope you enjoyed my article and you can find me on</p><p>You can find me on: <a href="https://github.com/amrdeveloper"><strong>GitHub</strong></a>, <a href="https://www.linkedin.com/in/amrdeveloper/"><strong>LinkedIn</strong></a>, and <a href="https://twitter.com/amrdeveloper"><strong>Twitter</strong></a>.</p><p>Enjoy Programming 😋.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5c48d9c60945" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Book Summary: Clang Compiler Frontend]]></title>
            <link>https://amrdeveloper.medium.com/book-summary-clang-compiler-frontend-d0c053298ada?source=rss-d6ca14e19099------2</link>
            <guid isPermaLink="false">https://medium.com/p/d0c053298ada</guid>
            <category><![CDATA[compilers]]></category>
            <category><![CDATA[llvm]]></category>
            <category><![CDATA[clang]]></category>
            <category><![CDATA[c]]></category>
            <dc:creator><![CDATA[Amr Hesham]]></dc:creator>
            <pubDate>Tue, 14 May 2024 10:54:21 GMT</pubDate>
            <atom:updated>2024-05-14T10:54:21.989Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/405/1*wYGH7Om-B8Sltxe1lCcbYA.jpeg" /><figcaption>Clang Compiler Frontend book cover</figcaption></figure><p>Hello everyone, I am Amr and i am a Software engineer who is interested in Compiler and Tools development and in this article i will try to write a summary for The <strong>Clang Compiler Frontend</strong> book so you can get an idea about what is the content and what to expect from it.</p><p>The book contains two parts and two Appendices which are.</p><ul><li>Part 1: Clang Setup and Architecture</li><li>Part 2: Clang Tools</li><li>Appendices: Compilation Database and Build Speed Optimization</li></ul><h3>Part 1: Clang Setup and Architecture</h3><p>The first part start with config and build Clang project with CMake and Ninja then moving to the architecture of the Clang compiler starting from Lexer, Parser and CodeGen with good level of details on how each part work and how the preprocessor work and why the C++ parser need to depend on Sema (Semantic analysis) and what is a FontEndAction and how to use it.</p><p>For me I know from previous talk that the C++ Parser will need to get some information from Sema to parse code successfully but i like that the author provide much deep details and use the LLDB to know what the program doing right now and which component run first.</p><p>After that the author go deeper to explain the design of AST (Abstract Syntax Tree) how it structured and how to traverse it in more than one way, for me this chapter was very important for me to optimize traversing the AST in my side project <a href="https://github.com/AmrDeveloper/ClangQL"><strong>ClangQL</strong></a><strong> </strong>because if for example you want to get only class information but you make the visitor recursion on the nodes you will got bad performance because it will traverse fields, methods …etc. and you don’t need them right now.</p><p>The last chapter in this part introduce the internal basic libraries and tools for example the LLVM team has his own testing framework that used beside Google test framework (<a href="https://www.geeksforgeeks.org/gtest-framework/">GTest</a>) and also they implemented containers data structures similar to std library but optimized for some common cases such as some String operations, Small Vector …etc</p><h3>Part 2: Clang tools</h3><p>The second is moving from the internal architecture of the Clang to the Clang tools starting with how the internal design of the linter which named Clang-tidy and how to config and use it with a practical example on how to create your own custom check that estimate estimate the complexity of a C++ class based on the number of methods it contains and report an error using the Diagnostic engine if the complexity is bigger than a parameter.</p><p>Next chapter will introduce advanced code analysis tools based on the Control Flow Graph (CFG) and how to construct CFG and write your own CFG checks.</p><p>Next chapter in this part will teach you how to create your own custom code modification tool to do some refactoring such as renaming methods and also how to integrate it with the linter to provide a modification fix for a check, also how to config and use the clang format tool and also how to format your custom modifications.</p><p>The last chapter in this part is about the integration with IDE and how the Clangd project provide many useful features such as code complete, go to definition, type hint, linting and code formatting and many other features to your IDE or Code Editor using the Language Server Protocol with many good details so you can imaging what happens under the hood from the file opened until you close the file and how code editor or IDE can communicate with Clangd, also what optimizations tricks the Clangd do to be fast.</p><h3>Appendix: Compilation Database</h3><p>In the first appendix the author talk about the compilation database (CDB) what it is and how to use it in a large project and also how it used by other tools such as the Clang-Tidy and Clangd.</p><h3>Appendix: Build Speed Optimization</h3><p>This appendix tech you how to use useful features from the Clang to optimize your build speed such as Modulemap, Precompiled headers and modules.</p><h3>Summary</h3><p>This book was very useful and exciting to read for me because i am already interested to learn more information about the Clang and LLVM internals and with those information you can work with tools such as linter and formatter with good knowledge how they are works and also implement your own tools, maybe you want to create some checks for your personal or company works or maybe generate a some information from AST or other many ideas for example the ClangQL project extract the AST informations to run SQL query on them.</p><p>Also i like how the author use the debugger to show you what exactly happens step by step.</p><p>I hope you enjoyed my article, and you can find me on</p><p>You can sponsor my work using GitHub Sponsor ❤️ from <a href="https://github.com/sponsors/AmrDeveloper"><strong>here</strong></a><strong>.</strong></p><p>You can find me on: <a href="https://github.com/amrdeveloper"><strong>GitHub</strong></a>, <a href="https://www.linkedin.com/in/amrdeveloper/"><strong>LinkedIn</strong></a>, and <a href="https://twitter.com/amrdeveloper"><strong>Twitter</strong></a>.</p><p>Thanks for reading and enjoy Programming 😋.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d0c053298ada" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Book Summary: Mastering the Java Virtual Machine An in-depth guide to JVM internals and performance…]]></title>
            <link>https://amrdeveloper.medium.com/book-summary-mastering-the-java-virtual-machine-an-in-depth-guide-to-jvm-internals-and-performance-76021bbd3b56?source=rss-d6ca14e19099------2</link>
            <guid isPermaLink="false">https://medium.com/p/76021bbd3b56</guid>
            <category><![CDATA[jvm-architecture]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[optimization]]></category>
            <category><![CDATA[jvm]]></category>
            <category><![CDATA[bytecode]]></category>
            <dc:creator><![CDATA[Amr Hesham]]></dc:creator>
            <pubDate>Fri, 19 Apr 2024 12:36:29 GMT</pubDate>
            <atom:updated>2024-04-19T12:36:29.841Z</atom:updated>
            <content:encoded><![CDATA[<h3>Book Summary: Mastering the Java Virtual Machine An in-depth guide to JVM internals and performance optimization</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*Imp1YF-K_d6Ytwc43qfHIg.jpeg" /></figure><p>Hello everyone, I am Amr and i am a Software engineer who is interested in Compiler and Tools development and in this article i will try to write a summary for <strong>Mastering the Java Virtual Machine</strong> book so you can get an idea about what is the content and what to expect from it.</p><p>The book contains four parts which are.</p><ul><li>Understanding the JVM</li><li>Memory Management and Execution</li><li>Alternative JVMs</li><li>Advanced Java Topics</li></ul><h3>Part 1: Understanding the JVM</h3><p>The author starts this part by taking you in the journey to why the JVM exists what are the advantages, and how it represents your code as bytecodes, it’s teaching you how to map your code to bytecode and how to read and understand the JVM class file structure,</p><p>Then it explains the most common bytecode instructions such as bytecode for Arithmetic and comparisons operations, Shifts, bitwise, conditions such as equal, and not equals for primitives and references, different method calls and how value is converted from type to other (Casting) and how JVM manipulate object (Set and Get), in my opinion the advantage here is that the author provide many practical examples and code snippets so after this part you can read and understand bytecodes for basics cases</p><h3>Part 2: Memory Management and Execution</h3><p>This part is very important for a developer who cares about optimizing your application, it takes you on a journey to the internals of JVM and how it deals with your code as a VM such as variables, operators, stack, heap, methods and native methods, also how JVM can give you more performance using the JIT (Just in time compilation), those information&#39;s are very important for example when you face a <a href="https://en.wikipedia.org/wiki/Stack_Overflow"><strong>StackOverflow</strong></a> exception with your recursive methods now you know what this exactly means and why it overflow!</p><p>Next it explains the different types of Garbage Collections algorithms how they are works and what are the different between, how to config the GC for your application and what are the recommended configuration, also how to select the right algorithm for your application.</p><h3>Part 3: Alternative JVMs</h3><p>This part introduces the Graal VM and explains the use case for it, comparing it with JVM to make it clear what are the advantages and disadvantages with real use cases and how you can create a native image for your application without the need to have VM installed on machine to be able to launch it</p><p>Next, it takes you on a journey to see different alternative JVMs implementations exists, and as we know from the previous part that changing Garbage Collector algorithm can led to different performance and pause time, you will learn that using a different JVM implementation will give you different trade off, so you will learn what are the different between the most six popular JVMs implementation (Eclipse J9, Amazon Corretto, Azul Zulu and Zin, IBM Semeru and Eclipse Temurin).</p><h3>Part 4: Advanced Java Topics</h3><p>This part is related to advanced topics in Java starting from Metadata and trade offs in frameworks then going to the most interesting topics for me (As a tools Developer)</p><p>Staring by the reflection and Dynamic Proxy topics, why they are important and what are the trade-offs of using them with interesting practical examples for both of them.</p><p>Next, it takes you to the Annotation Processor topic and how to take advantages of compile-time annotations to validate and generate code, why it’s different from runtime reflection and recreate the previous example in the Annotation processor.</p><p>For me I was interested in building tools using Annotation processor such as <a href="https://github.com/amrdeveloper/easyadapter"><strong>EasyAdapter</strong></a> library to help you to build UI Adapters easily using only Annotations, but it was the first time for me to learn about Dynamic Proxy and after some search i found that many Android libraries are built using it.</p><h3>Summary</h3><p>The book is very interesting to me and learned much good information about GC and how the JVM works in very low-level details, I recommend searching for examples for each concept trying to install the <a href="https://asm.ow2.io/"><strong>ASM</strong></a> library with the new java project and playing around with Bytecodes while reading the first two parts.</p><p>I hope you enjoyed my article, and you can find me on</p><p>You can find me on: <a href="https://github.com/amrdeveloper"><strong>GitHub</strong></a>, <a href="https://www.linkedin.com/in/amrdeveloper/"><strong>LinkedIn</strong></a>, and <a href="https://twitter.com/amrdeveloper"><strong>Twitter</strong></a>.</p><p>You can sponsor my work using GitHub Sponsor ❤️ from <a href="https://github.com/sponsors/AmrDeveloper"><strong>here</strong></a><strong>.</strong></p><p>Thanks for reading and enjoy Programming 😋.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=76021bbd3b56" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Book Summary: Learn LLVM 17]]></title>
            <link>https://amrdeveloper.medium.com/book-summary-learn-llvm-17-6602aa8109a6?source=rss-d6ca14e19099------2</link>
            <guid isPermaLink="false">https://medium.com/p/6602aa8109a6</guid>
            <category><![CDATA[clang]]></category>
            <category><![CDATA[book-review]]></category>
            <category><![CDATA[cpp]]></category>
            <category><![CDATA[llvm]]></category>
            <dc:creator><![CDATA[Amr Hesham]]></dc:creator>
            <pubDate>Tue, 20 Feb 2024 18:13:57 GMT</pubDate>
            <atom:updated>2024-02-20T18:13:57.956Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*b7UEme6D0BsL9ilO4TLU_Q.jpeg" /></figure><p>Hello everyone, I am Amr and i am a Software engineer who is interested in Compiler and Tools development and in this article i will try to write a summary for Learn LLVM 17 book so you can get an idea about what is the content and what to expect from it.</p><p>The book contains four parts which are</p><ul><li>The Basics of Compiler Construction with LLVM</li><li>From Source to Machine Code Generation</li><li>Taking LLVM to the Next Level</li><li>Roll Your Own Backend</li></ul><h4>Part 1: The Basics of Compiler Construction with LLVM</h4><p>The authors starts this part with step by step on how to install the LLVM on your system with the required dependencies then start to give you an overview about common the structure of the compiler and what is the goal of every pass.</p><p>After finishing the overview, the authors start with the first project which is a simple arithmetic expression language, this project it teach you how to define and read grammar, build a handwritten lexer, parser and convert from source code to Abstract Syntax Tree (AST) data resources, then going to Semantic analysis pass to validate this tree and make sure the program is valid for example checking if types and identifiers are valid and declared before used, then start the code generation pass which is generating LLVM IR from the AST and support the language with simple runtime library written in C and create call for it inside the code generation</p><h4>Part 2: From Source to Machine Code Generation</h4><p>In this part the authors start the second project which is a compiler for a subset of Modula-2 Programming language, this language supports types, generics and object-orientated programming here is an example from the book.</p><pre>MODULE Gcd;<br><br>PROCEDURE GCD(a, b: INTEGER) : INTEGER;<br>VAR t: INTEGER;<br>BEGIN<br> IF b = 0 THEN<br>  RETURN a;<br> END;<br> WHILE b # 0 DO<br>  t := a MOD b;<br>  a := b;<br>  b := t;<br> END;<br> RETURN a;<br>END GCD;<br><br>END Gcd.m</pre><p>The authors starts to define the grammar for the language which is now similar to real language not only arithmetic expression and show you the structure for the project then moving to preparing how to manage files and diagnostics and starting the lexer and the parser and AST which similar to the arithmetic expression language but for sure a lot bigger.</p><p>Then moving to performing semantic analysis which is now contains more analysis such as checking that variables or objects names are unique in the current scope and not declared twice, resolve types for constants without declaring it, and in assignment expression make sure that the value match the type for this variable</p><p>On the next chapters in this part the authors start to teach you about LLVM IR and SSA by generating IR from C code using Clang Compiler (Also i recommend to use the Compiler explore website too) and then starting to generate LLVM IR form the program AST with and implement optimization passes.</p><h4>Part 3: Taking LLVM to the Next Level</h4><p>In this part the authors start to teach you about the LLVM DSL TableGen language, The JIT (Just in time) Compiler and use LLVM tools in deteching issues, debugging, static analyzer and profiling then how to write your own tool using LibClang, In my opinion learning how to use and create tools with LibClang is very important so you can create a lot of good tools or using it to parse C code into AST allow your language to call C code and vice versa.</p><h4>Part 4: Roll Your Own Backend</h4><p>In this part the authors starts to teach you about how to add a new backend target for a CPU architecture not supported by LLVM</p><h4>Summary</h4><p>The book is very good. i liked that the authors stars with simple language first then moving to subset of real world language (Modula-2) with features that you see in most languages, also with well structure for code and compiler components not dummy.</p><p>In my opinion the book is good in both cases if you are want to start learning about compiler or have read some books before but interested to start learning how to create compiler using the LLVM infrastructure.</p><p>I hope you enjoyed my article and you can find me on</p><p>You can find me on: <a href="https://github.com/amrdeveloper"><strong>GitHub</strong></a>, <a href="https://www.linkedin.com/in/amrdeveloper/"><strong>LinkedIn</strong></a>, and <a href="https://twitter.com/amrdeveloper"><strong>Twitter</strong></a>.</p><p>Enjoy Programming 😋.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6602aa8109a6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The difference between infix function and operator in Kotlin]]></title>
            <link>https://itnext.io/the-difference-between-infix-function-and-operator-in-kotlin-38748383051c?source=rss-d6ca14e19099------2</link>
            <guid isPermaLink="false">https://medium.com/p/38748383051c</guid>
            <category><![CDATA[infix-function]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[operators]]></category>
            <category><![CDATA[precedence]]></category>
            <dc:creator><![CDATA[Amr Hesham]]></dc:creator>
            <pubDate>Fri, 07 Jul 2023 13:22:55 GMT</pubDate>
            <atom:updated>2023-07-07T13:22:55.411Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XcPPEbOxPh-lWmzvqSSc-w.png" /></figure><p>Hello everyone. Many of us use infix functions that come with Kotlin standard library as a replacement for operators. Since they have inline keyword and give us the same runtime performance as operators, you may think of them as just a named version of operators. But they are not totally the same as operators and today we will know why!</p><p>To help us understand the difference, let’s first talk about how an expression is evaluated in programming languages in general.</p><h4><strong>Expressions Evaluation</strong></h4><p>In a programming language, each expression has precedence in parsing, for example *and /has higher precedence than *and — that is what makes expressions like 2 * 2 + 2 evaluated to 6 not 8 because 2 * 2 will be evaluated first.</p><p>But what if two expressions have the same precedence? Which one will be evaluated first?</p><p>In this case, they will be evaluated from left to right; for example 1 + 2 + 3 will evaluate 1 + 2 first then 3 + 3 .</p><p>Now let&#39;s back to our main question about infix functions vs operators.</p><h4><strong>Infix functions vs operators</strong></h4><p>Infix function is just a syntax sugar that represents a function that takes two parameters but can call like an operator between two expressions. For example a function b is actually function(a, b) and from the compiler perspective, the infix function name is just a name like any other function. So if you named it and or plus that doesn’t mean compiler will trait it like &amp;&amp; or + operator and this is the main difference and that can cause big problems if you forget this simple difference, take this example.</p><pre>true || false &amp;&amp; false<br>true or false and false</pre><p>They look almost the same, but once you evaluate them you will find that they have a different result. Let’s see how they are evaluated.</p><h4><strong>The first expression</strong></h4><pre>true || false &amp;&amp; false</pre><p>In this expression, the and ( &amp;&amp; ) operator has higher precedence than the or ( ||) operator so it will evaluate first false &amp;&amp; false will be evaluated to false and now our expression looks like true || false and finally evaluated to true .</p><h4><strong>The second expression</strong></h4><pre>true or false and false</pre><p>This expression has no operators. They are two infix functions, and from the compiler prescriptive, they have the same precedence. So they will be evaluated from left to right, first true or false will be evaluated to true so our expression will be true and false and this will be evaluated to false .</p><h4><strong>Conclusion</strong></h4><p>When you want to use infix functions, make sure you explicitly know which part will be evaluated first and you can control that using Group expression (..) because expression inside Group always has the highest precedence and will be evaluate first.</p><p>I hope you enjoyed my article and you can find me on</p><p>You can find me on: <a href="https://github.com/amrdeveloper"><strong>GitHub</strong></a>, <a href="https://www.linkedin.com/in/amrdeveloper/"><strong>LinkedIn</strong></a>, <a href="https://twitter.com/amrdeveloper"><strong>Twitter</strong></a>.</p><p>Enjoy Programming 😋.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=38748383051c" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/the-difference-between-infix-function-and-operator-in-kotlin-38748383051c">The difference between infix function and operator in Kotlin</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How i created a query language for .git files (GQL)]]></title>
            <link>https://itnext.io/how-i-created-a-query-language-for-git-files-gql-fc431949dc4c?source=rss-d6ca14e19099------2</link>
            <guid isPermaLink="false">https://medium.com/p/fc431949dc4c</guid>
            <category><![CDATA[compilers]]></category>
            <category><![CDATA[git]]></category>
            <category><![CDATA[rust]]></category>
            <category><![CDATA[gql]]></category>
            <category><![CDATA[database]]></category>
            <dc:creator><![CDATA[Amr Hesham]]></dc:creator>
            <pubDate>Thu, 08 Jun 2023 15:04:09 GMT</pubDate>
            <atom:updated>2023-09-13T09:12:38.072Z</atom:updated>
            <content:encoded><![CDATA[<h3>I created a query language for .git files (GQL)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*j-h23LsuvsDwClnAerj1cg.png" /></figure><p>Hello everyone. Last month I got interested in Rust programming language and want to discover more about it. So I started to learn the basics and started to see the open source projects written in Rust. I also created one PR in the rust analyzer project; it does not depend on my knowledge of rust but on my general knowledge of Compilers and Static analysis. As usual, I love to learn new things by creating new projects with ideas that I am interested in.</p><h3>The idea</h3><p>I started to think about small ideas that I love to use, for example, a faster search CLI or some utility apps. But then I got a new cool idea.</p><p>While reading the Building git book (a book about building git from scratch), I learned what each file inside the .git folder does and how git store commits, branches and other data and manage its own database. So what if we have a query language that runs on those files?</p><h3>The Git Query Language (GQL)</h3><p>I decided to implement this query language, and I named it GQL. I was very excited to start this project because it was my first time implementing a query language. I decided to implement it from scratch, not converting .git files into an SQLite database and running normal SQL queries. And I thought it will be cool if, in the future, I can use the GQL engine as a part of a Git client or analyzer.</p><h3>The implementation of GQL</h3><p>The goal is to implement it into two parts. The first one is converting the GQL query into AST of nodes, then passing it to the engine to walk and execute it as an interpreter or in the future to convert this into virtual matching for GQL Byte code instructions.</p><p>The engine has the functionality to deal with .git files using the rust binding for git2 library so it can perform selecting, updating and deleting tasks, also storing the selected data into a data structure so we can perform filtering or sorting.</p><p>To simplify this implementation and I created a struct called GQLObject that can represent commit, branch, tag or any other object in this engine also to make it easy to perform sorting, searching, and filtering with single functions that deal with this type.</p><pre>pub struct GQLObject {<br>  pub attributes: HashMap&lt;String, String&gt;,<br>}</pre><p>The GQLObject is just a map of string as a key and value, so it can be general to put the info of any type. And now features like comparisons, filtering or sorting can be implemented easily on this strings map.</p><h3><strong>The current state</strong></h3><p>Over the last week, I implemented the selecting feature with conditions, filtering and sorting with optional limit and offset so you can write queries like this</p><pre>select * from commits<br>select name, email, title, message, time from commits<br>select * from commits order by name limit 1<br>select * from commits order by name limit 1 offset 1<br>select * from branches where ishead = &quot;true&quot;<br>select * from tags where name contains = &quot;2023&quot;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*g65kfCie0TxUWL1Zqj2eVg.gif" /></figure><h3><strong>Version 0.1.0 and 0.2.0 Updates</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/926/1*OBscQjRuCEAuDNyjR4oegg.gif" /></figure><p>After publishing this article and sharing the project i got amazing feedback from many peoples and feature requests so i started to implement many of them with the goal to be able to use SQL features for example</p><p>Now we have group by, Aggregation Functions and column name alias so you can perform more advanced query for example selecting top n contributors name and number of commits</p><pre>SELECT name, count(name) AS commit_num FROM commits GROUP BY name ORDER BY commit_num DES LIMIT 10</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RlVfvJc4E2q89Uq9GJOtsA.png" /></figure><h3><strong>The next step</strong></h3><p>Now the next step is to optimize the code and start to support more features, for example, imaging query for deleting all branches except the master.</p><pre>delete * from branches where name ! &quot;master&quot;</pre><p>Or pushing all or some branches to a remote repository using a single query. Maybe grouping and analyzing how many commits for each user in this month and many other things we can do.</p><p>The GQL project is a free open source, so everyone is most welcome to contribute, suggest features or report bugs.</p><p><a href="https://github.com/amrdeveloper/gql/">GitHub - AmrDeveloper/GQL: Git Query Language (GQL)</a></p><p>I am looking forward to your opinion and feedback 😋.</p><p>I hope you enjoyed my article and you can find me on</p><p>You can find me on: <a href="https://github.com/amrdeveloper"><strong>GitHub</strong></a>, <a href="https://www.linkedin.com/in/amrdeveloper/"><strong>LinkedIn</strong></a>, and <a href="https://twitter.com/amrdeveloper"><strong>Twitter</strong></a>.</p><p>Enjoy Programming 😋.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fc431949dc4c" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/how-i-created-a-query-language-for-git-files-gql-fc431949dc4c">How i created a query language for .git files (GQL)</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to create a C/C++ Static Code analysis tool]]></title>
            <link>https://itnext.io/how-to-create-a-c-c-static-code-analysis-tool-3247f9341a43?source=rss-d6ca14e19099------2</link>
            <guid isPermaLink="false">https://medium.com/p/3247f9341a43</guid>
            <category><![CDATA[clang]]></category>
            <category><![CDATA[code-analysis]]></category>
            <category><![CDATA[static-analysis]]></category>
            <category><![CDATA[cpp]]></category>
            <category><![CDATA[c]]></category>
            <dc:creator><![CDATA[Amr Hesham]]></dc:creator>
            <pubDate>Fri, 05 May 2023 12:57:14 GMT</pubDate>
            <atom:updated>2025-02-04T18:32:51.538Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cscVjXcTRl1FGcUL-ZUk7A.png" /></figure><p>Hello everyone. As a software engineer, static analysis is a very useful tool in our day to day work. In this article, we will learn how it works and create our own one for educational purposes to analyse C/C++ code depending on our rules.</p><h4>But first, What is Static Code Analysis?</h4><p>From the name, it’s that tool that analyses source code files but without executing them, and that’s the meaning of static. It can find issues such as Syntax errors, security vulnerabilities, coding standard violations, Undefined values and other types of violations.</p><p>You can check the list of static analysis tools from <a href="https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis"><strong>Wikipedia</strong></a> for almost all popular languages.</p><h4>How Static Code Analysis actually works?</h4><p>Your source code files, whatever they are (C, C++, Java or any other languages), are just a file with text, and it is hard to perform analysis on this code as pure text. So we need to put it in a data structure to be easy to traverse it as nodes such classes, functions, and variables. But how can we do that?</p><p>We can use the same technique that is used in compiling source code. Because the compiler also has the same requirement to traverse code and validate it before converting it to the executable file. This technique is called parsing. It reads the source file as text, and converts it to a tree data structure called Abstract syntax tree (AST). It holds the information about code and the position of every node in source files depending on the grammar of the language.</p><p>Now suppose that we created an AST from code, and we want to check that no function name contains _how can we do that?</p><p>Step 1: Traverse the tree and find all nodes that represent functions.<br>Step 2: For each node we will get the function name as a string.<br>Step 3: if the name contains _ we will report error with this function position.<br>Note: Remember I told you that AST hold the position too.</p><p>If you are confused don’t worry, we will do those steps in Code soon.</p><h4><strong>How can we create our C/C++ Static Code Analysis?</strong></h4><p>Our first task is how we can parse C/C++ source files into AST; there are three ways we can do this task,</p><p>The first solution is that we use tools that take grammar and generate the parser code for us. These tools are called parser generators. Examples of those tools are ANTLR, Bison, JavaCC and many others you can check the list from <a href="https://en.wikipedia.org/wiki/Comparison_of_parser_generators"><strong>Wikipedia</strong></a>.</p><p>The second solution is that we write our parse code from scratch to read text, check language grammar and build nodes of AST; this is called Hand Written parser. The advantage of this solution over the first one is that you can provide more helpful error messages and get more performance.</p><p>The third solution is to use a library that parses the code for us, so we can pass source files to it and receive the AST to perform the analysis. The advantage of this solution is that it is easy to use and will be updated if the language has a new version.</p><p>In this project, we will go with the third solution. Thanks to LLVM Team, we can use the Clang compiler components as libraries. So we will pass the source files to the library, and clang will handle syntax errors for us and type checking then it will provide us with an easy way to traverse the AST using Visitor design pattern and reporting errors.</p><p>In this article, we will perform two analysis tasks on our code:<br>1- Check that no function name contains _ at any position.<br>2- Check that no class inherit from more than one class</p><p>You can extend the project and do any kind of analysis you want.</p><h4>Now let&#39;s start coding!</h4><p>In this project, I will use C++20, Clang 15 and Cmake version 3.0.0+. To avoid making the article too long, I will not cover installing them. You can easily search for that.</p><p>Our CMakeList file will look like this to use the needed Clang libraries.</p><pre>cmake_minimum_required(VERSION 3.0.0)<br>project(checker VERSION 0.1.0)<br><br>set(CMAKE_CXX_STANDARD 20)<br>set(CMAKE_CXX_STANDARD_REQUIRED ON)<br><br>find_package(Clang REQUIRED CONFIG HINTS &quot;${LLVM_DIR}/lib/cmake/clang/&quot;)<br><br>add_executable(checker main.cpp)<br><br>target_include_directories(checker PRIVATE ${CLANG_INCLUDE_DIRS})<br>target_link_libraries(checker PRIVATE<br>  clangAST<br>  clangBasic<br>  clangFrontend<br>  clangTooling<br>)</pre><p>I named the project checker, you can replace it with your project name, and for this article, I wrote all the code inside main.cpp file.</p><p>Now, let’s setup the basic code for our project in C++,</p><p>First, we need to create a class that inherits from RecursiveASTVisitor so we can get any nodes we want to perform analysis.</p><pre>#include &lt;clang/Frontend/FrontendAction.h&gt;<br>#include &lt;clang/AST/RecursiveASTVisitor.h&gt;<br>#include &lt;clang/Tooling/Tooling.h&gt;<br><br>#include &lt;fstream&gt;<br><br>using namespace clang;<br>using namespace clang::tooling;<br><br>using namespace llvm;<br>using namespace llvm::cl;<br><br>class CheckerASTVisitor : public RecursiveASTVisitor&lt;CheckerASTVisitor&gt; {}</pre><p>Then create a class that inherits from ASTConsumer it will take the AST and pass it to our visitor class to traverse it</p><pre>class CheckerASTConsumer : public ASTConsumer {<br>public:<br>  auto HandleTranslationUnit(ASTContext &amp;context) -&gt; void override {<br>    CheckerASTVisitor visitor;<br>    visitor.TraverseDecl(context.getTranslationUnitDecl());<br>  }<br>};</pre><p>The last class is CheckerFrontendAction that creates a front end action and unique pointer of our AST consumer</p><pre>class CheckerFrontendAction : public ASTFrontendAction {<br>public:<br>  auto CreateASTConsumer(clang::CompilerInstance &amp;CI, llvm::StringRef InFile)<br>      -&gt; std::unique_ptr&lt;clang::ASTConsumer&gt; override {<br>    return std::make_unique&lt;CheckerASTConsumer&gt;();<br>  }<br>};</pre><p>Now in the main function, we will accept a file name from CLI, and pass it to the Clang library using our action</p><pre>auto main(int argc, const char **argv) -&gt; int {<br>  if (argc &lt; 2) {<br>    errs() &lt;&lt; &quot;Usage: &quot; &lt;&lt; argv[0] &lt;&lt; &quot; &lt;filename&gt;.cpp\n&quot;;<br>    return 1;<br>  }<br><br>  auto file_name = argv[1];<br><br>  // Read source file content to pass to clang<br>  std::ifstream if_stream(file_name);<br>  std::string content((std::istreambuf_iterator&lt;char&gt;(if_stream)),<br>                      (std::istreambuf_iterator&lt;char&gt;()));<br><br>  auto action = std::make_unique&lt;CheckerFrontendAction&gt;();<br>  <br>  // Pass action, file content and file name that used in error message<br>  clang::tooling::runToolOnCode(std::move(action), content, file_name);<br>  return 0;<br>}</pre><p>Now our setup is ready, so let&#39;s start our checks one by one.</p><p><strong>Check 1: Check that no function name contains </strong><strong>_ at any position.</strong></p><p>In any task, we need to ask ourselves an important question; which node do we need to check from the AST? In this case, it is FunctionDeclaration node. So let&#39;s visit it on our visitor. Our visitor will look like this now.</p><pre>class CheckerASTVisitor : public RecursiveASTVisitor&lt;CheckerASTVisitor&gt; {<br>public:<br>  auto VisitFunctionDecl(FunctionDecl *f) -&gt; bool { return true; }<br>};</pre><p>Each visit function gives you the node you want and wants you to return a boolean which is used to indicate whether the traversal should continue or not. Now let&#39;s implement our logic inside VisitFunctionDecl</p><pre>auto VisitFunctionDecl(FunctionDecl *f) -&gt; bool { <br>   // Get function name<br>   const auto name = f-&gt;getNameAsString();<br>   // Check if name contains _ at any position<br>   if (name.find(&quot;_&quot;) != std::string::npos) {<br>      // Get the diagnostic engine<br>      auto &amp;DE = f-&gt;getASTContext().getDiagnostics();<br>      // Create custom error message<br>      auto diagID = DE.getCustomDiagID(<br>          DiagnosticsEngine::Error,<br>          &quot;Function name contains `_`.&quot;);<br>      // Report our custom error<br>      DE.Report(f-&gt;getLocation(), diagID);<br>   }<br>   return true;<br>}</pre><p>Now let&#39;s create a test file test_name.cpp and test our analysis.</p><pre>void function_name() {}</pre><p>Let’s run our checker and see the output.</p><pre>checker test_name.cpp</pre><p>The output will look like this</p><pre>test_name.cpp:1:6: error: Function name contains `_`.<br>void function_name() {}<br>     ^<br>1 error generated.</pre><p>Our first task is successfully done. Let&#39;s start the next check.</p><p><strong>Check 2: Check that no class inherit from more than one class.</strong></p><p>Now the node we need to analysis it is the Class Declaration, so let’s start</p><pre>bool VisitCXXRecordDecl(CXXRecordDecl *D) {<br>  // Get number of bases classes<br>  auto number_of_bases = D-&gt;getNumBases();<br>  // Check if number of bases is bigger than one<br>  if (number_of_bases &gt; 1) {<br>    // Report custom error message like the last check<br>    auto &amp;DE = D-&gt;getASTContext().getDiagnostics();<br>    auto diagID = DE.getCustomDiagID(<br>        DiagnosticsEngine::Error, &quot;Class inhiert from more than one class.&quot;);<br>    auto DB = DE.Report(D-&gt;getLocation(), diagID);<br>  }<br>  return true;<br>}</pre><p>Now let’s create a test file class_inheritance_test.cpp and test our analysis.</p><pre>class One {};<br>class Two {};<br>class Three : One, Two {};</pre><p>The output will look like this</p><pre>class_inheritance_test.cpp:3:7: error: Class inhiert from more than one class.<br>class Three : One, Two {};<br>      ^<br>1 error generated.</pre><p>Our last task is successfully done 😉.</p><h4>Summary</h4><p>There are many more checks, and you can extend this project to be bigger and add many checks. You can customize error messages format, support configuration files to customize the analysis like production tools, and more features left for you to do.</p><p>I hope after this article, you understand how static analysis works.</p><p>I hope you enjoyed my article and you can find me on</p><p>You can find me on: <a href="https://github.com/amrdeveloper"><strong>GitHub</strong></a>, <a href="https://www.linkedin.com/in/amrdeveloper/"><strong>LinkedIn</strong></a>, <a href="https://twitter.com/amrdeveloper"><strong>Twitter</strong></a>.</p><p>Enjoy Programming 😋.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3247f9341a43" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/how-to-create-a-c-c-static-code-analysis-tool-3247f9341a43">How to create a C/C++ Static Code analysis tool</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I created a programming language and created games with it]]></title>
            <link>https://itnext.io/i-created-a-programming-language-and-created-games-with-it-5050c982b075?source=rss-d6ca14e19099------2</link>
            <guid isPermaLink="false">https://medium.com/p/5050c982b075</guid>
            <category><![CDATA[amun]]></category>
            <category><![CDATA[amun-programming-language]]></category>
            <category><![CDATA[llvm]]></category>
            <category><![CDATA[compilers]]></category>
            <category><![CDATA[programming-languages]]></category>
            <dc:creator><![CDATA[Amr Hesham]]></dc:creator>
            <pubDate>Sat, 22 Apr 2023 16:26:06 GMT</pubDate>
            <atom:updated>2023-04-26T23:07:20.760Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MK6ibg3xd-uDaqsz1_LY1w.png" /></figure><p>Hello everyone, today I will share with you the story about my programming language <strong>Amun</strong>, which is an open source low level general purpose language that compile to machine code using <strong>LLVM </strong>Framework.</p><p>The story begins two years ago, when I am as a self taught software engineer learning the subjects of computer science and in this time, I started to learn about Compiler design for the first time from Courses and Books, I created many small programming languages some of them are for specific goals like creating bots, drawing shapes …etc</p><p>I really loved the career of Compiler engineer and started to learn more about it, reading source code, try to design new features, watching live streams about compilers.</p><p>In the last year, I got the idea to design a high performance language that should be fast as C/C++ but to be very simple and easy to learn, also to give you some features to create good libraries and DSL (Domain specific Languages).</p><p>I already created a design for a small language with some features and concepts inspired by other languages such as C/C++, Go, Rust, Jai, Swift, Kotlin, and I started to simplify this design and named it <strong>Jot.</strong></p><p>What I want is a language that is simple as C and Go, no preprocessor, no garbage collection (remember I need a high performance language).</p><p>It also has such as Type inference and Generic Programming support, Compile time stuff, lambda expression, operator overloading, infix, prefix and postfix functions inspired by Swift, and some cool other features for examples.</p><p>Lambda expression with the ability to move lambda moved out of parentheses in function call and constructor</p><pre>var lambda = { printf(&quot;Hello from lambda!\n&quot;); };<br><br>fun let(value *void, callback *() void) {<br>    if (value != null) {  callback(); }<br>}<br><br>fun main() {<br>   let(null) { <br>       printf(&quot;Will never printed&quot;);<br>   }; <br>}</pre><p>Also, to come up with an easy way to iterate over arrays and strings.</p><pre>for array { printf(&quot;array[%d] = %d\n&quot;, it_index, it); } <br>for item : array { printf(&quot;array[%d] = %d\n&quot;, it_index, item); }<br>for item, index : array { printf(&quot;array[%d] = %d\n&quot;, index, item); }</pre><p>Tuples so you can create a collection of different type values and use it to make a function that return more than one type</p><pre>var tuple = (1, 2, &quot;Hello&quot;, 3, 4, &quot;World&quot;);<br><br>fun max_min(x int64, y int64) (int64, int64) {<br>   return if (x &gt; y) (x, y) else (y, x);<br>}</pre><p>Defer Statement that is useful for de allocate resources or closing streams at the end of current scope</p><pre>fun main() {<br>   var stream = open_stream();<br>   defer close_stream(stream);<br><br>   // Read and write from stream<br><br>   // Stream will closed here at the end of scope<br>}</pre><p>One of the most important goals is to have a cool and helpful compiler like rust, it should tell you messages that help you yo not only fix the bug but also understand more about problem and the language.</p><p>After some research, I found that the easiest way to create a high performance low level language is to use the LLVM Framework as a backend for the compiler so it can optimize and generate machine code for most of platforms. So I started to learn more about LLVM from Books and created a few projects with it.</p><p>In June 2022 I started to work on the compiler, and I decided to create it using C++ for many reasons such as high performance and LLVM is also created using C++ so I can easily found samples written in C++, also because I have some experience using it.</p><p>In Jan 2023 the language had most of the features that can help you to provide any programs that you can create in C but without Macros and i started to create simple programs and link with libraries such as OpenGL and Raylib to create simple GUI Applications.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cu9NYFyQf9BpTFiQ1i7IDA.png" /></figure><p>Then I started to work on features that can make creating libraries and applications easier, such as tuples, operator overloading, lambda, type alias, directives and also improve the compiler error message, I can’t covering all features in this article but I will write about them latter with cool samples.</p><p>After testing the features i ported a Pong game written using C++ and Raylib in my language and this is the result.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FlQt4s0haPGw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DlQt4s0haPGw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FlQt4s0haPGw%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/5c012c3de350b027ba3c79885ed7249b/href">https://medium.com/media/5c012c3de350b027ba3c79885ed7249b/href</a></iframe><p>Until this step, the language name was Jot, but I was surprised that there is already a language with the same name, so I searched for a new name, and I named it Amun. The name is inspired by Ancient Egyptian mythology when Amun was the chief deity of the Egyptian Empire.</p><p>The language is now still in development and everyone is most welcome to contribute to it. You can help with documentation, compiler, samples …etc.</p><p>You can follow the development on the GitHub repository, and there are more than 200 samples to over all language features, so feel free to star the project if you loved it.</p><p><a href="https://github.com/AmrDeveloper/amun">GitHub - AmrDeveloper/Amun: A Statically typed, compiled general purpose low level programming language built using C++ and LLVM Infrastructure framework designed to be simple and fast</a></p><p>Enjoy Programming and creating cool stuff 😇</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5050c982b075" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/i-created-a-programming-language-and-created-games-with-it-5050c982b075">I created a programming language and created games with it</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>