EoI : Lectures 1-5 complete

This commit is contained in:
2022-07-20 09:27:19 -04:00
parent 9eba81139d
commit f85c9615e4
24 changed files with 736 additions and 21 deletions

93
App/EoI/EoI_Viewer.tscn Normal file
View File

@@ -0,0 +1,93 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://Assets/Styles/Purple.EditorTheme.tres" type="Theme" id=1]
[ext_resource path="res://Assets/Branding/EoI_Class_Cover.png" type="Texture" id=2]
[ext_resource path="res://EoI/Scripts/EoI_Viewer.gd" type="Script" id=4]
[ext_resource path="res://Assets/Styles/Wine.EditorTheme.tres" type="Theme" id=5]
[node name="EoI_Panel" type="Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
theme = ExtResource( 5 )
script = ExtResource( 4 )
[node name="CourseBrand" type="TextureRect" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
rect_scale = Vector2( 0.2, 0.2 )
texture = ExtResource( 2 )
expand = true
stretch_mode = 6
[node name="Letter_FDialog" type="FileDialog" parent="."]
anchor_left = 0.35
anchor_top = 0.15
anchor_right = 0.45
anchor_bottom = 0.25
margin_right = 356.0
margin_bottom = 373.0
theme = ExtResource( 1 )
popup_exclusive = true
window_title = "Open a File"
mode = 0
access = 2
[node name="VBox" type="VBoxContainer" parent="."]
anchor_top = 0.196
anchor_right = 0.2
anchor_bottom = 1.0
margin_top = 2.39999
margin_right = -1.8
margin_bottom = -2.0
[node name="Eva_Interpret_Btn" type="Button" parent="VBox"]
margin_right = 203.0
margin_bottom = 32.0
rect_pivot_offset = Vector2( -123, -302 )
size_flags_vertical = 3
size_flags_stretch_ratio = 0.08
theme = ExtResource( 1 )
text = "Eva: Interpret"
[node name="Separator" type="HSeparator" parent="VBox"]
modulate = Color( 0.145098, 0.145098, 0.164706, 0 )
margin_top = 36.0
margin_right = 203.0
margin_bottom = 441.0
size_flags_vertical = 15
theme = ExtResource( 5 )
[node name="Back_Btn" type="Button" parent="VBox"]
margin_top = 445.0
margin_right = 203.0
margin_bottom = 478.0
rect_pivot_offset = Vector2( -123, -302 )
size_flags_vertical = 3
size_flags_stretch_ratio = 0.08
theme = ExtResource( 1 )
text = "Course Directory"
[node name="Editor_TEdit" type="TextEdit" parent="."]
anchor_left = 0.2
anchor_right = 0.625
anchor_bottom = 0.8
theme = ExtResource( 5 )
show_line_numbers = true
draw_tabs = true
highlight_all_occurrences = true
smooth_scrolling = true
minimap_draw = true
[node name="Output_TEdit" type="TextEdit" parent="."]
anchor_left = 0.2
anchor_top = 0.8
anchor_right = 0.625
anchor_bottom = 1.0
margin_left = 0.199997
theme = ExtResource( 5 )
[node name="Debug_TEdit" type="TextEdit" parent="."]
anchor_left = 0.625
anchor_right = 1.0
anchor_bottom = 1.0
theme = ExtResource( 5 )

View File

@@ -0,0 +1,110 @@
# Pipeline
Interpretation Involves **RUNTIME SEMANTICS**
***THE MEANING OF THE PROGRAM MODEL***
Compliation delegates semantics of runtime behavior to
***a TARGET language***
Interpetation deals with the semantics itself.
Types of Interpreter **implementation**:
* AST-based (recursive)
* Bytecode (Virtual Machines)
Types of Compiler **implementation**:
* Ahead-of-time (AOT)
* Just-in-time (JIT)
## Interpeter-AST:
**Translation Stage:**
1. Program Model
2. Lexer: Processing into token elements for a parser.
* Output : Tokens
3. Parser: Syntactic Analysis
* Output : Abstract Syntax Tree (AST)
**Runtime Stage:**
4. Interpeter
5. Runtime Behavior
## Interpreter-Bytecode:
**Translation Stage:**
1. Program Model
2. Lexer: Processing into token elements for a parser.
* Output : Tokens
3. Parser: Syntactic Analysis
* Output : Abstract Syntax Tree (AST)
4. Bytecode Emitter
5. Bytecode instructions primed.
**Runtime Stage:**
6. Interpreter
7. Runtime Behavior
**Types of Virtual Machine behavior:**
* Stack based
* Stack for operands and operators
* Result is always on top of stack
* Register based
* Virtual registers
* Result in accumulation register
* Map to real via register allocation
## Compiler Ahead-of-Time:
1. Program Model
2. Lexer: Processing into token elements for a parser.
* Output : Tokens
3. Parser: Syntactic Analysis
* Output : Abstract Syntax Tree (AST)
4. Code Generator
5. Intermediate representation primed
6. Target machine instruction set code generation
7. Target machine is intended interpretation platform.
8. Runtime Behavior.
## Compiler with LLVM platform:
1. Program Model
2. Lexer: Processing into token elements for a parser.
* Output : Tokens
3. Parser: Syntactic Analysis
* Output : Abstract Syntax Tree (AST)
4. LLVM IR generator
5. LLVM Native code generator
6. Target machine is intended interpretation platform
7. Runtime Behavior.
Lexer, and parser are considered **FRONT-END**.
Code Generation or byte-code gen or interpreter ast impelementation gen
for target instruction platform is considered **BACK-END**.
## Jit Compiler:
1. Program Model
2. Lexer: Processing into token elements for a parser.
* Output : Tokens
3. Parser: Syntactic Analysis
* Output : Abstract Syntax Tree (AST)
4. Bytecode Emitter
5. Bytecode fed to interpeter
6. Interetor may code gen immediately to target hardware platform or interpret ast directly.
7. Runtime Behavior.
## Transpiler:
1. Program Model in input langauge
2. Lexer: Processing into token elements for a parser.
* Output : Tokens
3. Parser: Syntactic Analysis
* Output : Abstract Syntax Tree (AST)
4. AST Transformation to target AST
5. Code generation
6. Program Model in output langauge

View File

@@ -0,0 +1,45 @@
# Eva Programming Langauge
Dynamic programming langauge.
Simple syntax, functional heart, OOP support.
## Eva Expressions:
```
(<type> <op1> <op2> ... <opN>)
```
Example:
```
(+ 5 10)
(set x 15)
(if (> x 10)
(print "ok")
(print "error")
)
```
```
(def foo (bar)
(+ bar 10)
)
```
```
(lambda (x) (* x x) 10)
```
## Design Goals
* Simple syntax: S-Expression
* Everything is an expression
* No explicit return, last evalulated expression is the result
* First class functions
* Static scope: all functions are closures
* Lambda functions
* Funcitonal programming
* Imperative programming
* Namespaces and modules
* OOP: Class or prototype based.

View File

View File

@@ -0,0 +1,38 @@
extends Node
var eva = preload("Eva.gd").new()
# UX --------------------------------------------------------
onready var Editor = get_node("Editor_TEdit")
onready var Output = get_node("Output_TEdit")
onready var Eva_Btn = get_node("VBox/Eva_Interpret_Btn")
onready var Back_Btn = get_node("VBox/Back_Btn")
func evaBtn_pressed():
eva.init(Editor.text)
var ast = eva.parse()
Output.text = eva.eval(ast)
func backBtn_pressed():
queue_free()
func _ready():
Eva_Btn.connect("pressed", self, "evaBtn_pressed")
Back_Btn.connect("pressed", self, "backBtn_pressed")

316
App/EoI/Scripts/Eva.gd Normal file
View File

@@ -0,0 +1,316 @@
extends Object
var SRegEx = preload("res://RegM/Scripts/SRegex.gd").new()
const TType : Dictionary = \
{
fmt_S = "Formatting",
cmt_SL = "Comment Single-Line",
cmt_ML = "Comment Multi-Line",
def_Start = "Expression Start",
def_End = "Expression End",
literal_Number = "LIteral: Number",
literal_String = "Literal: String",
operator = "Operator"
}
const Spec : Dictionary = \
{
TType.cmt_SL : "start // inline.repeat(0-)",
TType.cmt_ML : "start /* set(whitespace !whitespace).repeat(0-).lazy */",
TType.fmt_S : "start whitespace.repeat(1-).lazy",
TType.def_Start : "start \\(",
TType.def_End : "start \\)",
TType.literal_Number : \
"""start
set(+ \\-).repeat(0-1)
( set(0-9).repeat(1-) \\. ).repeat(0-1)
set(0-9).repeat(1-)
""",
TType.literal_String : "start \\\" !set( \\\" ).repeat(0-) \\\" ",
TType.operator : "start set(+ \\-)",
}
class Token:
var Type : String
var Value : String
func is_Literal():
return Type == TType.literal_Number || Type == TType.literal_String;
var SourceText : String
var Cursor : int
var SpecRegex : Dictionary
var Tokens : Array
var TokenIndex : int = 0
func compile_regex():
for type in TType.values() :
var \
regex = RegEx.new()
regex.compile( SRegEx.transpile(Spec[type]) )
SpecRegex[type] = regex
func init(programSrcText):
SourceText = programSrcText
Cursor = 0
TokenIndex = 0
if SpecRegex.size() == 0 :
compile_regex()
tokenize()
func next_Token():
var nextToken = null
if Tokens.size() > TokenIndex :
nextToken = Tokens[TokenIndex]
TokenIndex += 1
return nextToken
func reached_EndOfText():
return Cursor >= SourceText.length()
func tokenize():
Tokens.clear()
while reached_EndOfText() == false :
var srcLeft = SourceText.substr(Cursor)
var token = Token.new()
var error = true
for type in TType.values() :
var result = SpecRegex[type].search( srcLeft )
if result == null || result.get_start() != 0 :
continue
# Skip Comments
if type == TType.cmt_SL || type == TType.cmt_ML :
Cursor += result.get_string().length()
error = false
break
# Skip Whitespace
if type == TType.fmt_S :
var addVal = result.get_string().length()
Cursor += addVal
error = false
break
token.Type = type
token.Value = result.get_string()
Cursor += ( result.get_string().length() )
Tokens.append( token )
error = false
break;
if error :
var assertStrTmplt = "next_token: Source text not understood by tokenizer at Cursor pos: {value} -: {txt}"
var assertStr = assertStrTmplt.format({"value" : Cursor, "txt" : srcLeft})
assert(true != true, assertStr)
return
# ---------------------------------------------------------- Lexer
# ---------------------------------------------------------- Parser
# ---------------------------------------------------------- AST Node
const NType = \
{
literal_Number = "Literal: Number",
literal_String = "Literal: String",
op_Add = "+",
op_Mult = "*"
}
class ASTNode:
var Data : Array
func add_Expr( expr ):
Data.append(expr)
func add_TokenValue( token ):
Data.append( token.Value )
func set_Type( nType ):
Data.append(nType)
func arg( id ):
return Data[id]
func num_args():
return Data.size() - 1
func type():
return Data[0]
func is_Number():
return type() == NType.literal_Number
func is_String():
return type() == NType.literal_String
func string():
return arg(1).substr(1, arg(1).length() -2)
# Serialization ----------------------------------------------------
func array_Serialize(array, fn_objSerializer) :
var result = []
for entry in array :
if typeof(entry) == TYPE_ARRAY :
result.append( array_Serialize( entry, fn_objSerializer ))
elif typeof(entry) == TYPE_OBJECT :
fn_objSerializer.set_instance(entry)
result.append( fn_objSerializer.call_func() )
else :
result.append( entry )
return result
func to_SExpression():
# var expression = []
# if typeof(Value) == TYPE_ARRAY :
var \
to_SExpression_Fn = FuncRef.new()
to_SExpression_Fn.set_function("to_SExpression")
return array_Serialize( self.Data, to_SExpression_Fn )
# if typeof(Value) == TYPE_OBJECT :
# var result = [ Type, Value.to_SExpression() ]
# return result
# expression.append(Value)
# return expression
# Serialization END -------------------------------------------------
# ---------------------------------------------------------- AST Node END
var TokenType : Token
var NextToken : Token
# Gets the next token only if the current token is the specified intended token (tokenType)
func eat(tokenType):
var currToken = NextToken
assert(currToken != null, "eat: NextToken was null")
var assertStrTmplt = "eat: Unexpected token: {value}, expected: {type}"
var assertStr = assertStrTmplt.format({"value" : currToken.Value, "type" : tokenType})
assert(currToken.Type == tokenType, assertStr)
NextToken = next_Token()
return currToken
func parse():
NextToken = next_Token()
if NextToken.Type == TType.def_Start:
return parse_Expression()
if NextToken.is_Literal():
return parse_Literal()
func parse_Expression():
eat(TType.def_Start)
var node : ASTNode
if NextToken.Type == TType.operator:
node = parse_Operator()
var arg = 1
while NextToken.Type != TType.def_End:
node.add_Expr( parse_Literal() )
if NextToken.is_Literal():
node = parse_Literal()
eat(TType.def_End)
return node
func parse_Operator():
var \
node = ASTNode.new()
match NextToken.Value:
NType.op_Add:
node.set_Type(NType.op_Add)
NType.op_Mult:
node.set_Type(NType.op_Mult)
eat(TType.operator)
return node
func parse_Literal():
var \
node = ASTNode.new()
match NextToken.Type:
TType.literal_Number:
node.set_Type(NType.literal_Number)
node.add_TokenValue(NextToken)
eat(TType.literal_Number)
TType.literal_String:
node.set_Type(NType.literal_String)
node.add_TokenValue(NextToken)
eat(TType.literal_String)
return node
# ---------------------------------------------------------- Parser END
class_name Eva
# ---------------------------------------------------------- GLOBALS
# ---------------------------------------------------------- GLOBALS END
# ---------------------------------------------------------- UTILITIES
func throw( message ):
assert(false, message)
# ---------------------------------------------------------- UTILITIES END
func eval( ast ):
if ast.is_Number() :
return float(ast.arg(1))
if ast.is_String() :
return ast.string()
if ast.type() == NType.op_Add:
return String(eval( ast.arg(1) ) + eval( ast.arg(2) ))
if ast.type() == NType.op_Mult:
return String(eval( ast.arg(1) ) * eval( ast.arg(2) ))
throw("Unimplemented")