Artificial Languages
Requisites
Programing Language basics
Resources
Foundations
Complement
Advance
Manuals
https://tratt.net/laurie/blog/2023/compiled_and_interpreted_languages_two_ways_of_saying_tomato.html
https://ucsd-compilers-s23.github.io/
https://tratt.net/laurie/blog/2023/compiled_and_interpreted_languages_two_ways_of_saying_tomato.html
http://6.s081.scripts.mit.edu/sp19/
https://www.wolczko.com/CS294/index.html
Introduction
What is a language processor?
Language Processor Code
@startuml !theme mars skinparam groupInheritance 2 class "Language Processor" class "Artificial Language Processor" note left: It's called translator or computer language processor too. class "Natural Language Processor" class Compiler class Interpreter "Artificial Language Processor" <|-- Compiler "Artificial Language Processor" <|-- Interpreter "Artificial Language Processor" <|-- Assembler "Artificial Language Processor" <|-- Linker "Artificial Language Processor" <|-- Loader "Artificial Language Processor" <|-- Debugger "Artificial Language Processor" <|-- Profiler "Language Processor" <|-- "Artificial Language Processor" "Language Processor" <|-- "Natural Language Processor" note right: Sometimes called computational linguistics Compiler <|-- "High-level Programming Language" note left: You think by default in this kind of compiler. Compiler <|-- "Binary Translation" Compiler <|-- "Hardware Synthesis" Compiler <|-- "Database Query Compiler?" Compiler <|-- "Compiled Simulation" @enduml
Story
A misconception is Grace Hopper made the first compiler, indeed she didn’t. She did the first linker.
John Backus made “Speedcoding”, the first high-level programming language, in 1953 for the IBM 701 because software cost is higher than hardware cost. He made Fortran I for IBM 704 in 1954.
TODO. People.
1957. Internal Translator (IT): A Compiler for the 650. With J. W. Smith and H. R. Van Zoeren.
Programming languages generations
Research
ACM Symposium on Programming Language Design and Implementation (PLDI),
ACM Symposium on Principles of Programming Languages (POPL),
ACM Symposium on Principles and Practice of Parallel Programming (PPoPP), and
ACM Conference on Object-Oriented Programming Systems, Languages and Applications (OOPSLA).
Compiler Research: The Next 50 Years.
ACM SIGPLAN International Conference on Compiler Construction
https://github.com/imteekay/programming-language-research
Ecosystem
Communicative programming
Visual programming language
Esoteric programming language
JScrewIt
https://en.wikipedia.org/wiki/Esoteric_programming_language
Jobs
The economics of Programming Languages
Conferences, N. (2020, February 26). The Art of Code - Dylan Beattie. Youtube. Retrieved from https://www.youtube.com/watch?v=6avJHaC3C2U&ab_channel=NDCConferences
Conference, S. L. (2022, November 16). "Diagrammar: Simply Make Interactive Diagrams" by Pontus Granström (Strange Loop 2022). Youtube. Retrieved from https://www.youtube.com/watch?v=gT9Xu-ctNqI&ab_channel=StrangeLoopConference
google. (2022, December 16). closure-compiler. Retrieved from https://github.com/google/closure-compiler
Open-source.
Pietro. (2020, June 13). Compilers. Retrieved from https://pgrandinetti.github.io/compilers/page/can-i-get-a-job-in-compilers
Apa, C. (2021, November 03). Compiler engineering (Compiler Organization, C and C ++ standards, career, market, industry, etc.). Youtube. Retrieved from https://www.youtube.com/watch?v=aZbVvl_eeMA&ab_channel=ConferênciaAPA
LLVM
The LLVM Compiler Infrastructure Project. (2022, October 05). Retrieved from https://llvm.org
https://www.youtube.com/watch?v=BT2Cv-Tjq7Q&ab_channel=Fireship
Compiler architecture
Frontend & Backend
Design
@startuml map "Flujo de caracteres" as CharacterStream { codigo fuente => float calificacion = if (alumno=="Aho") then 10 else 6; tipo => Archivo[] } map "Código de máquina objetivo" as TargetMachineCode { } map "Tabla de símbolos" as SymbolTable { TOKEN => LEXEMA TIPO_DE_DATO => float IDENTIFICADOR_1 => calificacion ASIGNACION => = IF => if LPAREN => ( IDENTIFICADOR_2 => alumno EQ => == LITERAL => "Aho" RPAREN => ) THEN => then NUMERO => 10 ELSE => else NUMERO => 10 SEMICOLON => ; + => + ... => ... } class Simbolo { token // ¿cómo creamos sequencias \n significativas para ser manipuladas? lexema // ¿cuál es esa sequencia? } note right: por convenencia, algunas veces el token \n será igual al lexema, por ejemplo +, y\n por tanto será el lexema es omitido package "Análisis. FronEnd." <<Node>> { class "Analizador léxico" { reglas lexicas: {expresion regular: simbolo}[] escanea con expresiones regulares(codigo fuente): Simbolo[] guarda en tabla de simbolos(simbolo) } "Analizador léxico" -down-> SymbolTable: guarda CharacterStream -right--> "Analizador léxico" note top: Algunas veces llamado «Lexer», otras «Scanning» "Analizador léxico" -right--> "Analizador sintáctico" : flujo de simbolos -no terminales-. note top: Algunas veces llamado «parsing» "Analizador sintáctico" -right--> "Analizador semántico": árbol sintáctico (AST) class "Analizador sintáctico" { reglas de produccion crea un árbol basado en reglas gramaticales(símbolos): AST } class "Analizador semántico" { definición del lenguaje comprueba consistencia segun la definición del lenguaje() } "Analizador semántico" -right--> "Generador de código intermedio": árbol sintáctico (AST decorado) "Generador de código intermedio" -right--> "Optimización independiente de la máquina": representación intermedia (IR) } class "Generador de código intermedio" { código independiente de máquina para facilitar la reutilización genera código intermedio(): IR three-adress code } "Analizador léxico" <|-- "Lex" "Analizador léxico" <|-- "Flex" "Analizador léxico" <|-- "JFlex" "Analizador sintáctico" <|-- "Bison" "Analizador sintáctico" <|-- "Cup" "Analizador sintáctico" <|-- "Yacc" package "Síntesis. BackEnd." <<Node>> { "Optimización independiente de la máquina" -right--> "Optmización de código dependiente de la máquina": representación intermedia class "Optimización independiente de la máquina" { optimiza para ser más rápido o eficiente en uso de energia(IR): IR } "Optmización de código dependiente de la máquina" -right--> "Generador de código": código de máquina objetivo class "Optmización de código dependiente de la máquina" { optimiza usando los mecanismos del lenguaje objetivo(IR) } class "Generador de código" { traduce a lenguaje objetivo(): lenguaje objetivo usualmente código máquina } "Generador de código" -right--> TargetMachineCode "Generador de código" <|-- LLVM @enduml
https://www.scientificbulletin.upb.ro/rev_docs_arhiva/full83b_887019.pdf
Just in Time compilers
https://www.youtube.com/watch?v=d7KHAVaX_Rs&ab_channel=Computerphile
FAQ
Are compilers a theory of computation applied project?
Kind of.
Is a Parse tree a derivative tree?
No.
Why should you study Languages and Compilers?
Stevey's Blog Rants: Rich Programmer Food. (2022, November 09). Retrieved from https://steve-yegge.blogspot.com/2007/06/rich-programmer-food.html
What can compilers and cannot do?
Why There Are So Many Programming Languages?
Educational languages and other learning project ideas
Projects
https://projectbook.code.brettchalupa.com/command-line-interfaces/markdown-processor.html
FAQ
Why do I make a compiler to COOL, and not a real language such as C, C++, or Java?
Of course, some schools use C subsets to teach.
References
Alexander Aiken. 1996. Cool: a portable project for teaching compiler construction. SIGPLAN Not. 31, 7 (July 1996), 19–24. https://doi.org/10.1145/381841.381847 https://theory.stanford.edu/~aiken/software/cool/cool.html
PLT
PL/0 (Oberon??)
Visual Programming Languages. Google
Music language. Reading 26: Little Languages I. (2022, May 23). Retrieved from https://web.mit.edu/6.031/www/sp22/classes/26-little-languages-1
steinerkelvin. (2023, January 06). c-to-wasm-compiler-project. Retrieved from https://github.com/steinerkelvin/c-to-wasm-compiler-project
UpBeat. Alfred Aho's students made a language that transforms the stock market into music.
Logic programming. Valverde, J. A. R. (2022, October 31). JARV's Blog. Retrieved from https://jariaza.es
Language design. Language specification. Manual.
Your language must turn out compound objects.
Specification and Description Language (SDL)
Extended Backus–Naur form
Syntax diagram
https://en.wikipedia.org/wiki/Syntax_diagram
Dimensions.
Interpreters, Compilers.
Domain-specific languages (DSL), general-purpose language (GPL).
A language specification ≠ a language implementation.
You can follow the C99 specification and make an interpreter for it.
Examples
FAQ
How can a language's compiler be written in that language?
You have to have another previous compiler that can process your language.
ACM Classic: Reflections on Trusting Trust. (2022, December 31). Retrieved from https://web.archive.org/web/20070714062657/http://www.acm.org/classics/sep95
Writing a compiler in its own language. (2022, December 31). Retrieved from https://stackoverflow.com/questions/193560/writing-a-compiler-in-its-own-language
Bootstrapping still requires outside support. (2022, December 31). Retrieved from https://stackoverflow.com/questions/13537/bootstrapping-still-requires-outside-support
Bootstrapping a simple compiler from nothing. (2022, December 31). Retrieved from https://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html
Basic elements of Artificial Languages
Lexical Analysis (aka. scanning). Lexer
Where are you?
??
String to tokens.
writing a lexer with awk
tokenize easily
class Dicom:
def read():
return "0"
class ClassicImage:
def read():
return "1"
class LJPEG:
def read():
return "2"
def tokenize(string):
match = re.match(r'.+(\.(?P<Dicom>dcm)|(?P<ClassicImage>tiff|tff|png|jpg|tif)|(?P<LJPEG>ljpeg))', string, re.IGNORECASE)
if not match:
raise Exception("Pattern did not match the input string")
token = match.lastgroup
return globals()[token](string)
If you need more power, you can use named groups with regex
import re
def tokenize(text):
lexpos = 0
tokens = []
ignore_token_set = {'Whitespace'}
lexre = re.compile('(?i)(?P<Whitespace>[\s\n\r\f]+)|(?P<Mexico>M(e|é)xico)')
while lexpos < len(text):
match = lexre.match(text, lexpos)
token = match.lastgroup
lexema = match.group()
if token not in ignore_token_set:
tokens.append((token, lexema, lexpos))
lexpos = match.end()
return tokens
tokenize("""
Mexico
México
MEXICO
MÉXICO
""")
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <boost/regex.hpp>
using namespace std;
typedef pair<string, string> TokenPair;
vector<TokenPair> tokenize(const string& text) {
vector<TokenPair> tokens;
set<string> ignoreTokenSet = {"Whitespace"};
boost::regex lexre("(?i)(?<Whitespace>[\\s\\n\\r\\f]+)|(?<Mexico>M(e|é)xico)");
boost::smatch match;
string::const_iterator searchStart = text.begin();
string unrecognized = "Unrecognized";
while (searchStart != text.end()) {
if (boost::regex_search(searchStart, text.end(), match, lexre)) {
string token;
if (match["Whitespace"].matched) {
token = "Whitespace";
} else if (match["Mexico"].matched) {
token = "Mexico";
} else {
token = unrecognized;
}
string lexeme = match.str();
if (ignoreTokenSet.find(token) == ignoreTokenSet.end()) {
tokens.push_back({token, lexeme});
}
searchStart = match[0].second;
} else {
cout << "Unrecognized text: " << string(searchStart, text.end()) << endl;
break;
}
}
return tokens;
}
int main() {
string text = "Mexico\nMéxico\nMexicu\nMEXICO\nMÉXICO\n";
vector<TokenPair> tokens = tokenize(text);
for (const auto& [token, lexeme] : tokens) {
cout << "Token: " << token << ", Lexeme: " << lexeme << endl;
}
return 0;
}
A little interpreter called a calculator
Worked examples
Project
https://github.com/sanchezcarlosjr/compilers-uabc/blob/main/lexical-analysis-pa2/PA2.pdf
https://github.com/sanchezcarlosjr/compilers-uabc/tree/main/lexical-analysis-pa2
Syntax Analysis (aka. parsing)
TODO: Lexical versus Syntactic parsing.
Syntax diagram
Syntax diagrams (or railroad diagrams) are a way to represent a context-free grammar.
Grammar
In parsing, when people say grammar, they refer to context-free grammar.
Backtracking
Closure
First
Top-down parsing
Top-down parsing was initiated by Lewis and Stearns (1968) and Knuth (1971).
Recursive descent parser
LL(1) grammars
Algorithm.
References
LL(1) Parser Generator. (2020, March 24). Retrieved from https://www.cs.princeton.edu/courses/archive/spring20/cos320/LL1
Nonrecursive predictive parsing
Error recovery in predictive parsing
Bottom-up parsing
Reductions
Handle Pruning
Shift-reduce parsing
Conflicts During Shift-Reduce Parsing
LR parsing
LR parsers
Simple LR, LR(0)
More Power LR, Canonical-LR Parser LR(1)
Lookahead-LR parsers, LALR
Ambiguous Grammars
References
Home. (2021, April 22). Retrieved from https://ashutoshbsathe.github.io/yacv
LR(1) Parser Generator. (2012, December 02). Retrieved from https://jsmachines.sourceforge.net/machines/lr1.html
Sathe, A. (2021, March 07). Visualizing parsing using yacv: Yet Another Compiler Visualizer. Youtube. Retrieved from https://www.youtube.com/watch?v=BozB0O0__Qg&ab_channel=AshutoshSathe
Using Ambiguous Grammars
Parser Generators (aka parsing tools)
We need a pair of tools (Yacc, Lex), (Bison, Flex), (JFlex, CUP) in order to facilitate the construction of the front end of a compiler.
YACC
Parser Tools: lex and yacc-style Parsing. (2022, August 09). Retrieved from https://docs.racket-lang.org/parser-tools
BISON
Bison - GNU Project - Free Software Foundation. (2022, October 12). Retrieved from https://www.gnu.org/software/bison
CUP (Constructor of Useful Parsers)
ultimate-pa. (2022, October 12). javacup. Retrieved from https://github.com/ultimate-pa/javacup
https://github.com/ultimate-pa/javacup
Worked examples
Project
https://github.com/sanchezcarlosjr/compilers-uabc/tree/main/parser-pa3
https://github.com/sanchezcarlosjr/compilers-uabc/blob/main/parser-pa3/PA3.pdf
References
Detecting Ambiguity in Programming Language Grammars. Naveneetha Vasudevan and Laurence Tratt https://doi.org/10.1016/S0019-9958(82)91016-6
The Art of Computer Programming. Volume 5 – Syntactic Algorithms
Semantic Analysis
“Semantics analysis” is the third phase in a compiler that relates syntactic structures to give and verify meanings. It is the last “front end” phase too. It catches all remaining errors since parsing cannot catch them and some language constructs are not context-free. So, Semantics analysis income is AST from syntax analysis, and semantics analysis outcome is annotating AST, in fact, much of it can be expressed as recursive descent. In order words, you must check and annotate AST by requirements.
TODO: Denotational semantics
annote_ast(AST node)
annote an AST node
for child in node.children:
annote_ast(child)
finish to annotate an AST node
annote_ast(ast_from_syntax_analysis.root) # a pass
You must consider Semantic analysis requires multiple passes and it is highly dependent on the language’s requirements. However, we’re considering two typical problems in semantics analysis which are name resolution and typing.
Some language requirements are
- semantics must identify and remove duplicate code,
- semantics must check the entry point,
- semantics must identify and check typing (including signature and arity functions),
- semantics must identify unreachable code,
- semantics must check the inheritance tree,
- semantics must check the access modifier or specifier, e.g. private, protected, or public.
Symbol table
The symbol table is an abstract data type that keeps track of symbol information. It stores diverse symbol information such as location, kind of symbol, and scope. It can be built in the semantics analysis phase or lexical semantics analysis. Indeed, it can be used in runtime for metaprogramming o debugging. Here, we’ll build a symbol table for semantics analysis.
classDiagram
class SymbolTable {
enterScope()
find_symbol(x)
add_symbol(x)
check_scope(x)
exit_scope()
}
Symbol Table
https://ipfs.io/ipfs/QmQdtJry8zfndwXufxPNuTemQ7nzNwUYDxN9iAmrjKfgGm?filename=L09-LP-Handouts.pdf
Name resolution
It involves namespace (packages), scopes, visibility rules, overloading, and accessibility.
Scope
The scope or visibility of an identifier is the portion of the program (formally context or environment) in which that identifier applies. Scoping is useful because it prevents name collisions.
A simple language can not have any complex scoping logic, it can have only a global scoping or anything at all.
Is there a language to express scope precisely? No, we don’t any language.
Note that OOP languages have Access modifiers e.g. private, protected, or public. An access modifier is a static mechanism that allows to modification of the designed scope by the language specification.
Dynamically scoped or dynamic scope
The scope is context-dependent, but how we can determine the current context? Language specification has to say it since language can support static scope (also called lexical scope), dynamic scope, or both. You don’t think ahead a lot choosing one or another, use static scope.
The former means the context is where the identifier is declared and the context can not be changed. The latter means the context is determined in runtime.
Static scope example (it is a valid program in Python)
x = 99
def g():
print(x) # 99. The 'x' context is the global scope.
def f():
x = 10
g()
f()
Dynamic scope example (it is not a valid program in Python)
x = 99
def g():
print(x) # 10. The 'x' context is the "f" function.
def f():
local x = 10 # local is a fake keyword, but it ilustrates the point.
g()
f()
Bash and Perl support dynamic scope.
int x = 42;
int func() {
int x = 3840;
{
extern int x;
return x; // 42
}
}
x = 10 -- global variable
do -- new block
local x = x -- new 'x', with value 10
print(x) --> 10
x = x+1
do -- another block
local x = x+1 -- another 'x'
print(x) --> 12
end
print(x) --> 11
end
print(x) --> 10 (the global one)
Nested declaration identifiers
Languages support some nested declaration identifiers and others do not.
Python support nested declaration functions, so this program is invalid:
def f():
x = 10
def g():
print(x) # 10
f()
C cannot support nested declaration functions, so this program is invalid:
void f()
{
int x = 10;
int g()
{
printf("%d", x);
}
}
f();
Override identifiers
Forward declarations.
Name masking
Hoisting
Access modifier
t
Inheritance
Type system
Although the notion varies from language to language, type is a set of values and a set of operations on those values. In fact, low-level language and machine code don’t have any types. However, today the most reliable way to describe types is through the use of Algebraic Data Types. The goal of type systems and type checking is to ensure that operations are used with the correct types.
Types are computed up the AST from the leaves towards the root.
Type theory
Three kinds of languages:
- Statically types.
- Dynamically typed.
- Untyped.
They are not black and white. Real-world languages such that Java or C have “escape” mechanics, while Python’s new version has types.
Static typing means catching many programming errors at compile time and avoiding the overhead of running type checks. Dynamics typing proponents say static type systems are restrictive.
The type system is the piece of semantics analysis that does type checking and type inference.
Type checking is the process of verifying fully typed programs.
Type inference is the process of filling in missing type information.
The formalism for type checking is Rules of Inference.
Previous formal notations were regular expressions for the lexer and context-free grammar for the parsers. In a type system, the formal notation is the rule of inference. Those rules of inference are the form
The simplest examples are
A type system is sound if whenever then evaluates to a value of type . In other words, a sound-type system actually reflects the kind of value you get when you run the program.
is the turnstile symbol it means “it is provable that …”
Sound type rule examples.
Unsound type rule examples.
https://users.sussex.ac.uk/~mfb21/compilers/slides/6-handout.pdf
Type environments.
The type environments give types to the free identifiers in the current scope.
Let be a function from Identifiers to Types.
The sentence is read: Under the assumption that free variables have the types given by , it is probable that the expression has the type .
Subtyping.
lub(X,Y) the least upper bound.
Typing methods.
Other
Worked examples
References
Type Theory
Algebraic data type
Intermediate code generation
Run-Time environments
Code Optimization
Code Generator
Template engine model
A template engine, template processor, or template parser combines a template with data to produce a context-aware output. For instance, in this way, programmers can build multi-platform applications and let the compiler handle the differences.
Meta-programming
Magic variables/constants
Macros
#ifdef __unix__ /* __unix__ is usually defined by compilers targeting Unix systems */
# include <unistd.h>
#elif defined _WIN32 /* _WIN32 is usually defined by compilers targeting 32 or 64 bit Windows systems */
# include <windows.h>
#endif
Token Concatenation
Macro Expansion
Conditional Compilation
File Inclusion
Environment-Specific Definitions
# include
Bundlers
View engines
Target language
Computing Model
Name mangling
extern "C"
Java Native Interface
Memory, Stack, Heap
Linker
Static, Dynamic libraries, and Shared libraries
- Compilation - produces object code (.obj)
- Linking - produces executable code (.exe or .dll)
Dynamic Linking (.dll
in Windows, .so
in Linux).
! ldd ./slc
FAQ
How to make an executable without a linker, compiler, or assembler?
https://web.archive.org/web/20140130143820/http://robinhoksbergen.com/papers/howto_elf.html
How can you fix the shared library issues if you encounter any?
Worked example
Operational semantics
Garbage collection
Borrow checker model
Resource allocation is Initialization (RAII)
Threads
Coroutines await/async operations, and Event loop
https://love2d.org/wiki/love.run
function love.run()
if love.load then love.load(love.arg.parseGameArguments(arg), arg) end
-- We don't want the first frame's dt to include time taken by love.load.
if love.timer then love.timer.step() end
local dt = 0
-- Main loop time.
return function()
-- Process events.
if love.event then
love.event.pump()
for name, a,b,c,d,e,f in love.event.poll() do
if name == "quit" then
if not love.quit or not love.quit() then
return a or 0
end
end
love.handlers[name](a,b,c,d,e,f)
end
end
-- Update dt, as we'll be passing it to update
if love.timer then dt = love.timer.step() end
-- Call update and draw
if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
if love.graphics and love.graphics.isActive() then
love.graphics.origin()
love.graphics.clear(love.graphics.getBackgroundColor())
if love.draw then love.draw() end
love.graphics.present()
end
if love.timer then love.timer.sleep(0.001) end
end
end
Game Loop
http://gameprogrammingpatterns.com/game-loop.html
https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
Interpreter
REPL evaluate, print and loop
References
Crafting Interpreters. (2021, July 31). Retrieved from https://www.craftinginterpreters.com
Just in Time (JIT) compilers
https://www.youtube.com/watch?v=d7KHAVaX_Rs&ab_channel=Computerphile
Domain-specific languages (DSLs)
You don’t have to build a full programming language, but, indeed, some mini-language where you can build faster.
Diagrams
Drag and drop tools to draw sometimes are so frustrating for many reasons. So, why not make a language that draws things?
Graphviz, PlantUML, MermaidJS,
https://bpmn.io/toolkit/bpmn-js/examples/
Diagrams Through Ascii Art
Home | Penrose. (2023, January 01). Retrieved from https://penrose.cs.cmu.edu
Loop, Strange. "Diagrammar: Simply Make Interactive Diagrams - Strange Loop." 29 Jan. 2023, thestrangeloop.com/2022/diagrammar-simply-make-interactive-diagrams.html.
The Grammar of Graphics (Statistics and Computing)
Visual stories
lunafromthemoon. "RenJS." 7 Dec. 2022, renjs.net.
"The Ren'Py Visual Novel Engine." 4 Feb. 2023, www.renpy.org.
SVG
Template engines
Template processor
Build tools
Make, Gradle, CMake
Configuration tools
XML or JSON
"Timeline JS." Timeline JS, 19 Dec. 2022, timeline.knightlab.com/docs/json-format.html.
AWK
SED
GREP
Reactive programming
https://hackage.haskell.org/package/Yampa
https://copilot-language.github.io/
Modern Regex engines
Query languages
A data query language (DQL), a data definition language (DDL), a data control language (DCL), and a data manipulation language
SQL
OpenCypher
XPath
Markup language
Markdown, HTML, ReStructuredText, SGML
https://en.wikipedia.org/wiki/List_of_document_markup_languages
User interface markup language
CSS
SVG
QML
Symbolic mathematics
Your own DSL
Front End
Introduction to the Lambda Calculus
Quantum mechanics compilers
Quantum programming languages
Q Sharp
Language intelligence tools
Code completion
Syntax highlight
Marking errors and warnings
Memory leaks
Refactoring routines
Program synthesis
https://www.cs.utexas.edu/~bornholt/post/synthesis-explained.html
https://people.csail.mit.edu/asolar/SynthesisCourse/Lecture1.htm
Language Server Protocol
https://hjr265.me/blog/codemirror-lsp/
References
Parr, T. (2009). Language implementation patterns: create your own domain-specific and general programming languages. Language Implementation Patterns, 1-380.
OnSoftware. (2012, August 15). Domain-Specific Languages with Martin Fowler. Youtube. Retrieved from https://www.youtube.com/watch?v=ZfdAwV0HlEU&ab_channel=OnSoftware
Domain Specific Languages by Martin Fowler, with Rebecca Parsons 2010
DSL Guide. (2022, November 14). Retrieved from https://martinfowler.com/dsl.html
Swift, F. (2017, April 23). Writing Domain Specific Languages – Rahul Malik. Youtube. Retrieved from https://www.youtube.com/watch?v=YLeaRtB3GfY&ab_channel=FunctionalSwift
JetBrainsTV. (2021, November 11). Why we need domain-specific languages for non-developers. Youtube. Retrieved from https://www.youtube.com/watch?v=YuOb53LU_8A&ab_channel=JetBrainsTV
GeekcampSG. (2022, November 18). The L4 Compiler: a toolchain for a DSL for law - GeekcampSG 2022. Youtube. Retrieved from https://www.youtube.com/watch?v=VfA4rIX2VuU&ab_channel=GeekcampSG
Stuart, T. (2013). Understanding Computation: From Simple Machines to Impossible Programs. " O'Reilly Media, Inc.".