diff --git a/Editor/Assets/Branding/RDP_Class_cover_small.png b/App/Assets/Branding/RDP_Class_cover_small.png similarity index 100% rename from Editor/Assets/Branding/RDP_Class_cover_small.png rename to App/Assets/Branding/RDP_Class_cover_small.png diff --git a/Editor/Assets/Branding/RDP_Class_cover_small.png.import b/App/Assets/Branding/RDP_Class_cover_small.png.import similarity index 100% rename from Editor/Assets/Branding/RDP_Class_cover_small.png.import rename to App/Assets/Branding/RDP_Class_cover_small.png.import diff --git a/App/Assets/Branding/RegM_Class_cover_small.png b/App/Assets/Branding/RegM_Class_cover_small.png new file mode 100644 index 0000000..51d83ea Binary files /dev/null and b/App/Assets/Branding/RegM_Class_cover_small.png differ diff --git a/App/Assets/Branding/RegM_Class_cover_small.png.import b/App/Assets/Branding/RegM_Class_cover_small.png.import new file mode 100644 index 0000000..e4adf18 --- /dev/null +++ b/App/Assets/Branding/RegM_Class_cover_small.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/RegM_Class_cover_small.png-9128ac026427f18f59811eadf663fe9b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Branding/RegM_Class_cover_small.png" +dest_files=[ "res://.import/RegM_Class_cover_small.png-9128ac026427f18f59811eadf663fe9b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Editor/Assets/Fonts/DF_RecMonoSemiCasul.tres b/App/Assets/Fonts/DF_RecMonoSemiCasul.tres similarity index 100% rename from Editor/Assets/Fonts/DF_RecMonoSemiCasul.tres rename to App/Assets/Fonts/DF_RecMonoSemiCasul.tres diff --git a/Editor/Assets/Fonts/RecMonoSemicasual-Bold-1.084.ttf b/App/Assets/Fonts/RecMonoSemicasual-Bold-1.084.ttf similarity index 100% rename from Editor/Assets/Fonts/RecMonoSemicasual-Bold-1.084.ttf rename to App/Assets/Fonts/RecMonoSemicasual-Bold-1.084.ttf diff --git a/Editor/Assets/Fonts/RecMonoSemicasual-BoldItalic-1.084.ttf b/App/Assets/Fonts/RecMonoSemicasual-BoldItalic-1.084.ttf similarity index 100% rename from Editor/Assets/Fonts/RecMonoSemicasual-BoldItalic-1.084.ttf rename to App/Assets/Fonts/RecMonoSemicasual-BoldItalic-1.084.ttf diff --git a/Editor/Assets/Fonts/RecMonoSemicasual-Italic-1.084.ttf b/App/Assets/Fonts/RecMonoSemicasual-Italic-1.084.ttf similarity index 100% rename from Editor/Assets/Fonts/RecMonoSemicasual-Italic-1.084.ttf rename to App/Assets/Fonts/RecMonoSemicasual-Italic-1.084.ttf diff --git a/Editor/Assets/Fonts/RecMonoSemicasual-Regular-1.084.ttf b/App/Assets/Fonts/RecMonoSemicasual-Regular-1.084.ttf similarity index 100% rename from Editor/Assets/Fonts/RecMonoSemicasual-Regular-1.084.ttf rename to App/Assets/Fonts/RecMonoSemicasual-Regular-1.084.ttf diff --git a/Editor/Assets/Styles/Editor.SytleBoxFlat.tres b/App/Assets/Styles/Editor.SytleBoxFlat.tres similarity index 100% rename from Editor/Assets/Styles/Editor.SytleBoxFlat.tres rename to App/Assets/Styles/Editor.SytleBoxFlat.tres diff --git a/Editor/Assets/Styles/EditorTheme.tres b/App/Assets/Styles/EditorTheme.tres similarity index 100% rename from Editor/Assets/Styles/EditorTheme.tres rename to App/Assets/Styles/EditorTheme.tres diff --git a/Editor/Persistent.tscn b/App/Persistent.tscn similarity index 100% rename from Editor/Persistent.tscn rename to App/Persistent.tscn diff --git a/Editor/Lectures/Lecture.1.gd b/App/RDP/Lectures/Lecture.1.gd similarity index 100% rename from Editor/Lectures/Lecture.1.gd rename to App/RDP/Lectures/Lecture.1.gd diff --git a/Editor/Lectures/Lecture.10.gd b/App/RDP/Lectures/Lecture.10.gd similarity index 100% rename from Editor/Lectures/Lecture.10.gd rename to App/RDP/Lectures/Lecture.10.gd diff --git a/Editor/Lectures/Lecture.11.gd b/App/RDP/Lectures/Lecture.11.gd similarity index 100% rename from Editor/Lectures/Lecture.11.gd rename to App/RDP/Lectures/Lecture.11.gd diff --git a/Editor/Lectures/Lecture.12.gd b/App/RDP/Lectures/Lecture.12.gd similarity index 100% rename from Editor/Lectures/Lecture.12.gd rename to App/RDP/Lectures/Lecture.12.gd diff --git a/Editor/Lectures/Lecture.13.gd b/App/RDP/Lectures/Lecture.13.gd similarity index 100% rename from Editor/Lectures/Lecture.13.gd rename to App/RDP/Lectures/Lecture.13.gd diff --git a/Editor/Lectures/Lecture.14.gd b/App/RDP/Lectures/Lecture.14.gd similarity index 100% rename from Editor/Lectures/Lecture.14.gd rename to App/RDP/Lectures/Lecture.14.gd diff --git a/Editor/Lectures/Lecture.15.gd b/App/RDP/Lectures/Lecture.15.gd similarity index 100% rename from Editor/Lectures/Lecture.15.gd rename to App/RDP/Lectures/Lecture.15.gd diff --git a/Editor/Lectures/Lecture.16.gd b/App/RDP/Lectures/Lecture.16.gd similarity index 100% rename from Editor/Lectures/Lecture.16.gd rename to App/RDP/Lectures/Lecture.16.gd diff --git a/Editor/Lectures/Lecture.17.gd b/App/RDP/Lectures/Lecture.17.gd similarity index 100% rename from Editor/Lectures/Lecture.17.gd rename to App/RDP/Lectures/Lecture.17.gd diff --git a/Editor/Lectures/Lecture.18.gd b/App/RDP/Lectures/Lecture.18.gd similarity index 99% rename from Editor/Lectures/Lecture.18.gd rename to App/RDP/Lectures/Lecture.18.gd index 35c9622..1a8a5f4 100644 --- a/Editor/Lectures/Lecture.18.gd +++ b/App/RDP/Lectures/Lecture.18.gd @@ -724,7 +724,7 @@ class Parser: return node # > ClassDeclaration - # SuperClass + # ClassExtension # : extends Identifier # ; func parse_ClassExtension(): @@ -1256,8 +1256,7 @@ onready var TextOut = GScene.get_node("TextOutput") onready var FDialog = GScene.get_node("Letter_FDialog") onready var FD_Btn = GScene.get_node("ParseLetterFile_Btn") -func tout(text): - TextOut.insert_text_at_cursor(text) + func parse_file(path): var \ diff --git a/Editor/Lectures/Lecture.2.gd b/App/RDP/Lectures/Lecture.2.gd similarity index 100% rename from Editor/Lectures/Lecture.2.gd rename to App/RDP/Lectures/Lecture.2.gd diff --git a/Editor/Lectures/Lecture.3..gd b/App/RDP/Lectures/Lecture.3..gd similarity index 100% rename from Editor/Lectures/Lecture.3..gd rename to App/RDP/Lectures/Lecture.3..gd diff --git a/Editor/Lectures/Lecture.4.gd b/App/RDP/Lectures/Lecture.4.gd similarity index 100% rename from Editor/Lectures/Lecture.4.gd rename to App/RDP/Lectures/Lecture.4.gd diff --git a/Editor/Lectures/Lecture.5.gd b/App/RDP/Lectures/Lecture.5.gd similarity index 100% rename from Editor/Lectures/Lecture.5.gd rename to App/RDP/Lectures/Lecture.5.gd diff --git a/Editor/Lectures/Lecture.6.gd b/App/RDP/Lectures/Lecture.6.gd similarity index 100% rename from Editor/Lectures/Lecture.6.gd rename to App/RDP/Lectures/Lecture.6.gd diff --git a/Editor/Lectures/Lecture.7.gd b/App/RDP/Lectures/Lecture.7.gd similarity index 100% rename from Editor/Lectures/Lecture.7.gd rename to App/RDP/Lectures/Lecture.7.gd diff --git a/Editor/Lectures/Lecture.8.gd b/App/RDP/Lectures/Lecture.8.gd similarity index 100% rename from Editor/Lectures/Lecture.8.gd rename to App/RDP/Lectures/Lecture.8.gd diff --git a/Editor/Lectures/Lecture.9.gd b/App/RDP/Lectures/Lecture.9.gd similarity index 100% rename from Editor/Lectures/Lecture.9.gd rename to App/RDP/Lectures/Lecture.9.gd diff --git a/Notes.Lecture.1.txt b/App/RDP/Lectures/Notes.Lecture.1.txt similarity index 92% rename from Notes.Lecture.1.txt rename to App/RDP/Lectures/Notes.Lecture.1.txt index ef34c51..2c85686 100644 --- a/Notes.Lecture.1.txt +++ b/App/RDP/Lectures/Notes.Lecture.1.txt @@ -1,92 +1,92 @@ -Following the first lecture of "Building a Parser from scratch" -By Dmitry Soshnikov. - - -Lecture 1: - - -Phases: - -Data - Text Content -Processor - Tokenizer -Data - Tokens -Processor - Parser -Data - AST - - -Example of syntaxes : - -S-Expression : - -(class Point - (begin - - (def constructor (self x y) - (begin - (set (prop self x) x) - (set (prop self y) y) - ) - ) - - (def calc (self) - (+ (prop self x) - (prop self y) - ) - ) - ) -) - -(var p (new Point 10 20)) - -((prop p calc) p) - - -User Syntax : - -class Point -{ - def constructor( x, y ) - { - this.x = x; - this.y = y; - } - - def calc() { - return this.x + this.y; - } -} - -let -p = new Point(10, 20); -p.calc(); - - -Tokenizer - Lexial Analysis : Uses Regular Expressions (Optimal) -Parser - Syntactic Analysis : Uses Backus-Naur Form - - -Backus-Naur Example : - -Program - : StatementList - ; - -StatementList - : BlockStatement - | IfStatement - | FunctionDeclaration - ... - ; - -FunctionDeclaration - : def Identifier ( Arguments ) BlockStatement - ; - - -Hand-written parsers : - Use recursive descent. - -Automatically generated - All kinds of stuff... - - +Following the first lecture of "Building a Parser from scratch" +By Dmitry Soshnikov. + + +Lecture 1: + + +Phases: + +Data - Text Content +Processor - Tokenizer +Data - Tokens +Processor - Parser +Data - AST + + +Example of syntaxes : + +S-Expression : + +(class Point + (begin + + (def constructor (self x y) + (begin + (set (prop self x) x) + (set (prop self y) y) + ) + ) + + (def calc (self) + (+ (prop self x) + (prop self y) + ) + ) + ) +) + +(var p (new Point 10 20)) + +((prop p calc) p) + + +User Syntax : + +class Point +{ + def constructor( x, y ) + { + this.x = x; + this.y = y; + } + + def calc() { + return this.x + this.y; + } +} + +let +p = new Point(10, 20); +p.calc(); + + +Tokenizer - Lexial Analysis : Uses Regular Expressions (Optimal) +Parser - Syntactic Analysis : Uses Backus-Naur Form + + +Backus-Naur Example : + +Program + : StatementList + ; + +StatementList + : BlockStatement + | IfStatement + | FunctionDeclaration + ... + ; + +FunctionDeclaration + : def Identifier ( Arguments ) BlockStatement + ; + + +Hand-written parsers : + Use recursive descent. + +Automatically generated + All kinds of stuff... + + diff --git a/Editor/Lectures/AST_Viewer.tscn b/App/RDP/RDP_Viewer.tscn similarity index 62% rename from Editor/Lectures/AST_Viewer.tscn rename to App/RDP/RDP_Viewer.tscn index 2db95be..5f1b2b5 100644 --- a/Editor/Lectures/AST_Viewer.tscn +++ b/App/RDP/RDP_Viewer.tscn @@ -1,11 +1,13 @@ -[gd_scene load_steps=3 format=2] +[gd_scene load_steps=4 format=2] [ext_resource path="res://Assets/Styles/EditorTheme.tres" type="Theme" id=1] [ext_resource path="res://Assets/Branding/RDP_Class_cover_small.png" type="Texture" id=2] +[ext_resource path="res://RDP/Scripts/RDP_Viewer.gd" type="Script" id=3] -[node name="Control" type="Control"] +[node name="RDP_Panel" type="Panel"] anchor_right = 1.0 anchor_bottom = 1.0 +script = ExtResource( 3 ) [node name="CourseBrand" type="TextureRect" parent="."] anchor_right = 1.0 @@ -15,8 +17,18 @@ texture = ExtResource( 2 ) expand = true stretch_mode = 6 -[node name="TextOutput" type="TextEdit" parent="."] +[node name="Tokens_TOut" type="TextEdit" parent="."] anchor_left = 0.25 +anchor_right = 0.5 +anchor_bottom = 1.0 +grow_horizontal = 0 +theme = ExtResource( 1 ) +readonly = true +highlight_current_line = true +show_line_numbers = true + +[node name="AST_TOut" type="TextEdit" parent="."] +anchor_left = 0.5 anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 0 @@ -27,7 +39,6 @@ show_line_numbers = true minimap_draw = true [node name="Letter_FDialog" type="FileDialog" parent="."] -visible = true anchor_left = 0.35 anchor_top = 0.15 anchor_right = 0.45 @@ -48,3 +59,12 @@ margin_left = 2.0 margin_right = 0.071991 margin_bottom = 14.6 text = "Parse a letter file" + +[node name="Back_Btn" type="Button" parent="."] +anchor_top = 0.95 +anchor_right = 0.247 +anchor_bottom = 0.992 +margin_left = 2.0 +margin_right = 0.071991 +margin_bottom = 2.59998 +text = "Course Directory" diff --git a/App/RDP/Readme.md b/App/RDP/Readme.md new file mode 100644 index 0000000..6d799d5 --- /dev/null +++ b/App/RDP/Readme.md @@ -0,0 +1,13 @@ +# Building a parser from scratch + +[Img](https://i.imgur.com/rEzWwGs.png) + +## Lecutres + +Contains gd scripts that show the resulting progress at the end of each of their corresponding lectures. + +## Scripts + +Contains a final set of scripts for the course that cleans up the implementation to a final state. + + diff --git a/App/RDP/Scripts/Lexer.gd b/App/RDP/Scripts/Lexer.gd new file mode 100644 index 0000000..50bbf99 --- /dev/null +++ b/App/RDP/Scripts/Lexer.gd @@ -0,0 +1,230 @@ +extends Object + + +class_name Lexer + + +const TokenType : Dictionary = \ +{ + # Comments + cmt_SL = "Comment Single Line", + cmt_ML = "Comment Multi-Line", + + # Formatting + fmt_S = "Formatting String", + + # Delimiters + delim_Comma = "Comma Delimiter", + delim_SMR = "Symbol Member Resolution", + + # Statements + def_End = "Statement End", + def_BStart = "Block Start", + def_BEnd = "Block End", + def_Var = "Variable Declaration", + def_Class = "Class", + + # Iteration + def_While = "While", + def_Do = "Do-While", + def_For = "For", + + # Procedures + def_Proc = "Procedure Declaration", + def_Return = "Return", + + # Conditional + def_If = "If Statement", + def_Else = "Else Statement", + + # Expressions + expr_PStart = "Parenthesis Start", + expr_PEnd = "Parenthesis End", + expr_SBStart = "Bracket Start", + expr_SBEnd = "Bracket End", + expr_New = "New Expression", + expr_Super = "Super Expression", + expr_Extends = "Class Extension", + + # Operators + + # Logical + op_Relational = "Relational", + op_Equality = "Equality", + op_LAnd = "Logical And", + op_LOr = "Logical Or", + op_LNot = "Logical Not", + + # Arithmetic + op_CAssign = "ComplexAssignment", + op_Assign = "Assignment", + op_Additive = "AdditiveOperator", + op_Multiplicative = "MultiplicativeOperator", + + # Literals + literal_BTrue = "True", + literal_BFalse = "False", + literal_Number = "Number", + literal_String = "String", + literal_Null = "Null Value", + + # Symbols + sym_This = "This Reference", + sym_Identifier = "User Identifier", +} + +const Spec : Dictionary = \ +{ + # Comments + TokenType.cmt_SL : "^\\/\\/.*", + TokenType.cmt_ML : "^\\/\\*[\\s\\S]*?\\*\\/", + + # Formatting + TokenType.fmt_S : "^\\s+", + + # Delimiters + TokenType.delim_Comma : "^,", + TokenType.delim_SMR : "^\\.", + + # Statements + TokenType.def_End : "^;", + TokenType.def_BStart : "^{", + TokenType.def_BEnd : "^}", + TokenType.def_Var : "^\\blet\\b", + TokenType.def_Class : "^\\bclass\\b", + + # Iteration + TokenType.def_While : "^\\bwhile\\b", + TokenType.def_Do : "^\\bdo\\b", + TokenType.def_For : "^\\bfor\\b", + + # Procedures + TokenType.def_Proc : "^\\bdef\\b", + TokenType.def_Return : "^\\breturn\\b", + + # Conditional + TokenType.def_If : "^\\bif\\b", + TokenType.def_Else : "^\\belse\\b", + + # Expressions + TokenType.expr_PStart : "^\\(", + TokenType.expr_PEnd : "^\\)", + TokenType.expr_SBStart : "^\\[", + TokenType.expr_SBEnd : "^\\]", + TokenType.expr_New : "^\\bnew\\b", + TokenType.expr_Super : "^\\bsuper\\b", + TokenType.expr_Extends : "^\\bextends\\b", + + #Operators + + # Logical + TokenType.op_Relational : "^[>\\<]=?", + TokenType.op_Equality : "^[=!]=", + TokenType.op_LAnd : "^&&", + TokenType.op_LOr : "^\\|\\|", + TokenType.op_LNot : "^!", + + # Arithmetic + TokenType.op_CAssign : "^[*\\/\\+\\-]=", + TokenType.op_Assign : "^=", + TokenType.op_Additive : "^[+\\-]", + TokenType.op_Multiplicative : "^[*\\/]", + + # Literals + TokenType.literal_BTrue : "^\\btrue\\b", + TokenType.literal_BFalse : "^\\bfalse\\b", + TokenType.literal_Number : "^\\d+", + TokenType.literal_String : "^\"[^\"]*\"", + TokenType.literal_Null : "^\\bnull\\b", + + # Symbols + TokenType.sym_This : "^\\bthis\\b", + TokenType.sym_Identifier : "^\\w+" +} + + +class Token: + var Type : String + var Value : String + + +var SourceText : String +var Cursor : int +var SpecRegex : Dictionary +var Tokens : Array +var TokenIndex : int = 0 + + +func compile_regex(): + for type in TokenType.values() : + var \ + regex = RegEx.new() + regex.compile( Spec[type] ) + + SpecRegex[type] = regex +# SpecRegex[type].compile( Spec[type] ) + +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 TokenType.values() : + var result = SpecRegex[type].search( srcLeft ) + if result == null || result.get_start() != 0 : + continue + + # Skip Comments + if type == TokenType.cmt_SL || type == TokenType.cmt_ML : + Cursor += result.get_string().length() + error = false + break + + # Skip Whitespace + if type == TokenType.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 diff --git a/App/RDP/Scripts/Parser.gd b/App/RDP/Scripts/Parser.gd new file mode 100644 index 0000000..d16de32 --- /dev/null +++ b/App/RDP/Scripts/Parser.gd @@ -0,0 +1,1072 @@ +extends Object + +const NodeType = \ +{ + program = "Program", + + expr_Assignment = "Assignment Expression", + expr_Call = "Call Expression", + expr_ClassExtend = "Class Extension", + expr_Binary = "Binary Expression", + expr_Logical = "Logical Expression", + expr_Member = "Member Expression", + expr_New = "New Expression", + expr_Super = "Super Expression", + expr_This = "This Expression", + expr_Unary = "Unary Expression", + + def_Class = "Class Declaration", + def_Procedure = "Function Declaration", + def_Variable = "Variable Declaration", + + literal_Bool = "Boolean Literal", + literal_Numeric = "Numeric Literal", + literal_String = "String Literal", + literal_Null = "Null Literal", + + stmt_Block = "Block Statement", + stmt_Conditional = "Conditional Statement", + stmt_Expression = "Expression Statement", + stmt_Empty = "Empty Statement", + stmt_Variable = "Variable Statement", + stmt_While = "While Statement", + stmt_DoWhile = "Do-While Statement", + stmt_For = "For Statement", + stmt_Return = "Return Statement", + + sym_Identifier = "Identifier" +} + +class PNode: + var Type : String + var Value # Not specifing a type implicity declares a Variant type. + + 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 = [ Type ] + + if typeof(Value) == TYPE_ARRAY : + var \ + to_SExpression_Fn = FuncRef.new() + to_SExpression_Fn.set_function("to_SExpression") + + var array = array_Serialize( self.Value, to_SExpression_Fn ) + + expression.append(array) + return expression + + if typeof(Value) == TYPE_OBJECT : + var result = [ Type, Value.to_SExpression() ] + return result + + expression.append(Value) + return expression + + func to_Dictionary(): + if typeof(Value) == TYPE_ARRAY : + var \ + to_Dictionary_Fn = FuncRef.new() + to_Dictionary_Fn.set_function("to_Dictionary") + + var array = array_Serialize( self.Value, to_Dictionary_Fn ) + var result = \ + { + Type = self.Type, + Value = array + } + return result + + if typeof(Value) == TYPE_OBJECT : + var result = \ + { + Type = self.Type, + Value = self.Value.to_Dictionary() + } + return result + + var result = \ + { + Type = self.Type, + Value = self.Value + } + return result + + + +var SLexer : Script = preload("res://RDP/Scripts/Lexer.gd") +var TokenType = SLexer.TokenType +var NextToken : Lexer.Token +var Lexer + + + +# --------------------------------------------------------------------- HELPERS + +# 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 = Lexer.next_Token() + + return currToken + +func is_Literal(): + return \ + NextToken.Type == TokenType.literal_Number \ + || NextToken.Type == TokenType.literal_String \ + || NextToken.Type == TokenType.literal_BTrue \ + || NextToken.Type == TokenType.literal_BFalse \ + || NextToken.Type == TokenType.literal_Null + +# BinaryExpression +# : MultiplicativeExpression +# | AdditiveExpression +# ; +func parse_BinaryExpression(parse_fn, operatorToken): + var left = parse_fn.call_func() + + while NextToken.Type == operatorToken: + var operator = eat(operatorToken) + var right = parse_fn.call_func() + + var \ + nestedNode = PNode.new() + nestedNode.Type = NodeType.expr_Binary + nestedNode.Value = [] + nestedNode.Value.append(operator.Value) + nestedNode.Value.append(left) + nestedNode.Value.append(right) + + left = nestedNode; + + return left + +# LogicalExpression +# : LogicalAndExpression +# | LogicalOrExpression +# ; +func parse_LogicalExpression(parse_fn, operatorToken): + var left = parse_fn.call_func() + + while NextToken.Type == operatorToken : + var operator = eat(operatorToken).Value + var right = parse_fn.call_func() + + var \ + nestedNode = PNode.new() + nestedNode.Type = NodeType.expr_Logical + nestedNode.Value = [] + nestedNode.Value.append(operator) + nestedNode.Value.append(left) + nestedNode.Value.append(right) + + left = nestedNode + + return left + +# ------------------------------------------------------------------ END HELPERS + +# Parses the text program description into an AST. +func parse(lexer): + Lexer = lexer + NextToken = lexer.next_Token() + + return parse_Program() + +# > parse +# Program +# : StatementList +# : Literal +# ; +func parse_Program(): + var \ + node = PNode.new() + node.Type = NodeType.program + node.Value = parse_StatementList(null) + + if node.Value == [ null ] : + print("WTF") + + return node + +# > Program +# > BlockStatement +# StatementList +# : Statement +# | StatementList Statement -> Statement ... +# ; +func parse_StatementList(endToken): + var statementList = [ parse_Statement() ] + + while NextToken != null && NextToken.Type != endToken : + statementList.append( parse_Statement() ) + + return statementList + +# > StatementList +# > If_Statement +# > WhileStatement +# Statement +# : ExpressionStatement +# | BlockStatement +# | EmptyStatement +# | VariableStatement +# | If_Statement +# | IterationStatement +# | FunctionDeclaration +# | ReturnStatement +# | ClassDeclaration +# ; +func parse_Statement(): + if NextToken == null : + return null + + match NextToken.Type : + TokenType.def_If : + return parse_If_Statement() + TokenType.def_End : + return parse_EmptyStatement() + TokenType.def_BStart : + return parse_BlockStatement() + TokenType.def_Var : + return parse_VariableStatement() + TokenType.def_While : + return parse_IterationStatement() + TokenType.def_Do : + return parse_IterationStatement() + TokenType.def_For : + return parse_IterationStatement() + TokenType.def_Proc: + return parse_FunctionDeclaration() + TokenType.def_Return: + return parse_ReturnStatement() + TokenType.def_Class: + return parse_ClassDeclaration() + + return parse_ExpressionStatement() + +# If Statement +# : if ( Expression ) Statement +# | if ( Expression ) Statement else Statement +# ; +func parse_If_Statement(): + eat(TokenType.def_If) + + eat(TokenType.expr_PStart) + var condition = parse_Expression() + eat(TokenType.expr_PEnd) + + var consequent = parse_Statement() + var alternative = null + + if NextToken != null && NextToken.Type == TokenType.def_Else : + eat(TokenType.def_Else) + alternative = parse_Statement() + + var \ + node = PNode.new() + node.Type = NodeType.stmt_Conditional + node.Value = [ condition, consequent, alternative ] + + return node + +# > Statement +# EmptyStatement +# ; +func parse_EmptyStatement(): + eat(TokenType.def_End) + + var \ + node = PNode.new() + node.Type = NodeType.stmt_Empty + + return node + +# > Statement +# BlockStatement +# : { OptStatementList } +# ; +func parse_BlockStatement(): + eat(TokenType.def_BStart) + + var \ + node = PNode.new() + node.Type = NodeType.stmt_Block + + if NextToken.Type != TokenType.def_BEnd : + node.Value = parse_StatementList(TokenType.def_BEnd) + else : + node.Value = [] + + eat(TokenType.def_BEnd) + + return node + +# > Statement +# VariableStatement +# : VariableStatementInit StatementEnd +# ; +func parse_VariableStatement(): + var varStatement = parse_VariableStatementInit() + + eat(TokenType.def_End) + + return varStatement + +# > VariableStatement +# VariableStatementInit +# : VarDeclare VariableDeclarationList +# ; +func parse_VariableStatementInit(): + eat(TokenType.def_Var) + + var declarations = parse_VariableDeclarationList() + + var \ + node = PNode.new() + node.Type = NodeType.stmt_Variable + node.Value = declarations + + return node + +# > Statement +# IterationStatement +# : WhileStatement +# | DoWhileStatement +# | ForStatement +# ; +func parse_IterationStatement(): + match NextToken.Type: + TokenType.def_While : + return parse_WhileStatement() + TokenType.def_Do : + return parse_DoWhileStatement() + TokenType.def_For : + return parse_ForStatement() + +# > IterationStatement +# WhileStatement +# : while ( Expression ) Statement +# ; +func parse_WhileStatement(): + eat(TokenType.def_While) + + eat(TokenType.expr_PStart) + var condition = parse_Expression() + eat(TokenType.expr_PEnd) + + var body = parse_Statement() + var \ + node = PNode.new() + node.Type = NodeType.stmt_While + node.Value = [ condition, body ] + + return node + +# > IterationStatement +# DoWhileStatement +# : do Statement while ( Expression ) +# ; +func parse_DoWhileStatement(): + eat(TokenType.def_Do) + + var body = parse_Statement() + + eat(TokenType.def_While) + + eat(TokenType.expr_PStart) + var condition = parse_Expression() + eat(TokenType.expr_PEnd) + + eat(TokenType.def_End) + + var \ + node = PNode.new() + node.Type = NodeType.stmt_DoWhile + node.Value = [ condition, body ] + + return node + +# > IterationStatement +# ForStatement +# : for ( +# OptForStatementInit ; +# OptExpression ; +# OptExpression +# ) +# Statement +# ; +func parse_ForStatement(): + eat(TokenType.def_For) + + eat(TokenType.expr_PStart) + + var init = null + var condition = null + var update = null + + if NextToken.Type != TokenType.def_End : + init = parse_ForStatementInit() + eat(TokenType.def_End) + + if NextToken.Type != TokenType.def_End : + condition = parse_Expression() + eat(TokenType.def_End) + + if NextToken.Type != TokenType.expr_PEnd : + update = parse_Expression() + + eat(TokenType.expr_PEnd) + + var body = parse_Statement() + + var \ + node = PNode.new() + node.Type = NodeType.stmt_For + node.Value = [ init, condition, update, body ] + + return node + +# > ForStatement +# ForStatementInit +# : VariableStatemetnInit +# | Expression +# ; +func parse_ForStatementInit(): + if NextToken.Type == TokenType.def_Var : + return parse_VariableStatementInit() + + return parse_Expression() + +# > Statement +# FunctionDeclaration +# : FuncDeclare ( OptFomralParameterList ) BlockStatement +# ; +func parse_FunctionDeclaration(): + + eat(TokenType.def_Proc) + + var name = parse_Identifier() + + eat(TokenType.expr_PStart) + + var params + if NextToken.Type != TokenType.expr_PEnd : + params = parse_FormalParameterList() + else : + params = [] + + eat(TokenType.expr_PEnd) + + var body = parse_BlockStatement() + + var \ + node = PNode.new() + node.Type = NodeType.def_Procedure + node.Value = [ name, params, body ] + + return node + +# > FunctionDeclaration +# FormalParameterList +# : Identifier +# | FormalParameterList , Identifier +# ; +func parse_FormalParameterList(): + var params = [ parse_Identifier() ] + + while NextToken.Type == TokenType.delim_Comma : + eat(TokenType.delim_Comma) + params.append(parse_Identifier()) + + return params + +# > Statement +# ReturnStatement +# : return OptExpression +# ; +func parse_ReturnStatement(): + eat(TokenType.def_Return) + + var argument = null + if NextToken.Type != TokenType.def_End : + argument = parse_Expression() + + eat(TokenType.def_End) + + var \ + node = PNode.new() + node.Type = NodeType.stmt_Return + node.Value = argument + + return node + +# > Statement +# ClassDeclaration +# : class Identifier OptClassExtends BLockStatement +# ; +func parse_ClassDeclaration(): + eat(TokenType.def_Class) + + var identifier = parse_Identifier() + var superClass = null + + if NextToken.Type == TokenType.expr_Extends : + superClass = parse_ClassExtension() + + var body = parse_BlockStatement() + + var \ + node = PNode.new() + node.Type = NodeType.def_Class + node.Value = [ identifier, superClass, body ] + + return node + +# > ClassDeclaration +# ClassExtension +# : extends Identifier +# ; +func parse_ClassExtension(): + eat(TokenType.expr_Extends) + + return parse_Identifier() + +# > Statement +# ExpressionStatement +# : Expression +# ; +func parse_ExpressionStatement(): + var expression = parse_Expression() + eat(TokenType.def_End) + + var \ + node = PNode.new() + node.Type = NodeType.stmt_Expression + node.Value = expression + + return expression + +# > ExpressionStatement +# > If_Statement +# > WhileStatement +# > PrimaryExpression +# Expression +# : AssignmentExpression +# ; +func parse_Expression(): + return parse_AssignmentExpression() + +# > VariableStatement +# VariableDeclarationList +# : VariableDeclaration +# | VariableDelcarationList , VariableDeclaration -> VariableDelcaration , ... +func parse_VariableDeclarationList(): + var \ + declarations = [] + declarations.append(parse_VariableDeclaration()) + + while NextToken.Type == TokenType.delim_Comma : + eat(TokenType.delim_Comma) + declarations.append(parse_VariableDeclaration()) + + return declarations + +# > VariableDeclarationList +# VariableDeclaration +# : Identifier OptVariableInitalizer +# ; +func parse_VariableDeclaration(): + var identifier = parse_Identifier() + var initalizer + if NextToken.Type != TokenType.def_End \ + && NextToken.Type != TokenType.delim_Comma : + initalizer = parse_VariableInitializer() + else : + initalizer = null + + var \ + node = PNode.new() + node.Type = NodeType.def_Variable + node.Value = [ identifier, initalizer ] + + return node + +# > VariableDeclaration +# VariableInitializer +# : Assignment AssignmentExpression +# ; +func parse_VariableInitializer(): + eat(TokenType.op_Assign) + + return parse_AssignmentExpression() + +# > Expression +# > VariableInitializer +# > AssignmentExpression +# AssignmentExpression +# : RelationalExpression +# | ResolvedSymbol AssignmentOperator AssignmetnExpression +# ; +func parse_AssignmentExpression(): + var left = parse_LogicalOrExpression() + + if NextToken.Type != TokenType.op_Assign \ + && NextToken.Type != TokenType.op_CAssign : + return left + + var assignmentOp; + + if NextToken.Type == TokenType.op_Assign : + assignmentOp = eat(TokenType.op_Assign) + elif NextToken.Type == TokenType.op_CAssign : + assignmentOp = eat(TokenType.op_CAssign) + + var \ + node = PNode.new() + node.Type = NodeType.expr_Assignment + node.Value = \ + [ + assignmentOp.Value, + left, + parse_AssignmentExpression() + ] + + return node + +# > VariableDeclaration +# > ParenthesizedExpression +# Identifier +# : IdentifierSymbol +# ; +func parse_Identifier(): + var name = eat(TokenType.sym_Identifier).Value + + var \ + node = PNode.new() + node.Type = NodeType.sym_Identifier + node.Value = name + + return node + +# > AssignmentExpression +# Logical Or Expression +# : LogicalAndExpression Logical_Or LogicalOrExpression +# | LogicalOrExpression +# ; +func parse_LogicalOrExpression(): + var \ + parseFn = FuncRef.new() + parseFn.set_instance(self) + parseFn.set_function("pasre_LogicalAndExpression") + + return parse_LogicalExpression(parseFn, TokenType.op_LOr) + +# > LogicaOrExpression +# Logical And Expression +# : EqualityExpression Logical_And LogicalAndExpression +# | EqualityExpression +# ; +func pasre_LogicalAndExpression(): + var \ + parseFn = FuncRef.new() + parseFn.set_instance(self) + parseFn.set_function("parse_EqualityExpression") + + return parse_LogicalExpression(parseFn, TokenType.op_LAnd) + +# Equality Operators: ==, != +# +# > LogicalAndExpression +# EqualityExpression +# : RelationalExpression EqualityOp RelationalExpression +# | RelationalExpression +# ; +func parse_EqualityExpression(): + var \ + parseFn = FuncRef.new() + parseFn.set_instance(self) + parseFn.set_function("parse_RelationalExpression") + + return parse_BinaryExpression(parseFn, TokenType.op_Equality) + +# Relational Operators: >, >=, <, <= +# +# > EqualityExpression +# Relational Expression +# : AdditiveExpression +# | AdditiveExpression RelationalOp RelationalExpression +# ; +func parse_RelationalExpression(): + var \ + parseFn = FuncRef.new() + parseFn.set_instance(self) + parseFn.set_function("parse_AdditiveExpression") + + return parse_BinaryExpression(parseFn, TokenType.op_Relational) + +# > RelationalExpression +# AdditiveExpression +# : MultiplicativeExpression +# | AdditiveExpression AdditiveOp MultiplicativeExpression -> MultiplicativeExpression AdditiveOp ... Literal +# ; +func parse_AdditiveExpression(): + var \ + parseFn = FuncRef.new() + parseFn.set_instance(self) + parseFn.set_function("parse_MultiplicativeExpression") + + return parse_BinaryExpression(parseFn, TokenType.op_Additive) + +# > AdditiveExpression +# MultiplicativeExpression +# : UnaryExpressioon +# : MultiplicativeExpression MultiplicativeOp UnaryExpression -> UnaryExpression MultiplicativeOp ... Literal +# ; +func parse_MultiplicativeExpression(): + var \ + parseFn = FuncRef.new() + parseFn.set_instance(self) + parseFn.set_function("parse_UnaryExpression") + + return parse_BinaryExpression(parseFn, TokenType.op_Multiplicative) + +# > MultiplicativeExpression +# > UnaryExpression +# UnaryExpression +# : ResolvedSymbol +# | AdditiveOp UnaryExpression +# | Logical_Not UnaryExpression +# ; +func parse_UnaryExpression(): + var operator + match NextToken.Type: + TokenType.op_Additive: + operator = eat(TokenType.op_Additive).Value + TokenType.op_LNot: + operator = eat(TokenType.op_LNot).Value + + if operator == null : + return parse_ResolvedSymbol() + + var \ + node = PNode.new() + node.Type = NodeType.expr_Unary + node.Value = [ operator, parse_UnaryExpression() ] + + return node; + +# > UnaryExpression +# > PrimaryExpression +# ResolvedSymbol (LeftHandExpression) +# : MemberExpression +# ; +func parse_ResolvedSymbol(): + return parse_FunctionExpression() + +# > ResolvedSymbol +# FunctionExpression +# : Super +# | MemberExpression +# | CallExpression +# ; +func parse_FunctionExpression(): + if NextToken.Type == TokenType.expr_Super : + return parse_CallExpression(parse_SuperExpression()) + + var member = parse_MemberExpression() + + if NextToken.Type == TokenType.expr_PStart : + return parse_CallExpression(member) + + return member + +# > FunctionExpression +# Super +# : super +# ; +func parse_SuperExpression(): + eat(TokenType.expr_Super) + + var \ + node = PNode.new() + node.Type = NodeType.expr_Super + + return node + +# > ResolvedSymbol +# MemberExpression +# : PrimaryExpression +# | MemberExpression . Identifier +# | MemberExpression [ Expression ] +# ; +func parse_MemberExpression(): + var expression = parse_PrimaryExpression() + + while NextToken.Type == TokenType.delim_SMR || NextToken.Type == TokenType.expr_SBStart : + if NextToken.Type == TokenType.delim_SMR : + eat(TokenType.delim_SMR) + + var member = parse_Identifier() + + var \ + node = PNode.new() + node.Type = NodeType.expr_Member + node.Value = [ false, expression, member ] + + expression = node + + if NextToken.Type == TokenType.expr_SBStart : + eat(TokenType.expr_SBStart) + + var sbExpression = parse_Expression() + + eat(TokenType.expr_SBEnd) + + var \ + node = PNode.new() + node.Type = NodeType.expr_Member + node.Value = [ true, expression, sbExpression ] + + expression = node + + return expression + +# > FunctionExpression +# CallExpression +# : Callee Arguments +# ; +# +# Callee +# : MemberExpression +# | CallExpression +# ; +func parse_CallExpression(callee): + var \ + callExpression = PNode.new() + callExpression.Type = NodeType.expr_Call + callExpression.Value = \ + [ + callee, + parse_Arguments() + ] + + if NextToken.Type == TokenType.expr_PStart : + callExpression = parse_CallExpression(callExpression) + + return callExpression + +# > CallExpression +# Arugments +# : ( OptArgumentList ) +# ; +func parse_Arguments(): + eat(TokenType.expr_PStart) + + var argumentList = null + + if NextToken.Type != TokenType.expr_PEnd : + argumentList = parse_ArgumentList() + + eat(TokenType.expr_PEnd) + + return argumentList + +# > Arguments +# ArgumentList +# : AssignmentExpression +# | ArgumentList , AssignmentExpression +# ; +func parse_ArgumentList(): + var argumentList = [ parse_AssignmentExpression() ] + + while NextToken.Type == TokenType.delim_Comma : + eat(TokenType.delim_Comma) + + argumentList.append( parse_AssignmentExpression() ) + + return argumentList + + +# > MemberExpression +# PrimaryExpression +# : Literal +# | ParenthesizedExpression +# | Identifier +# | ThisExpression +# | NewExpression +# ; +func parse_PrimaryExpression(): + if is_Literal(): + return parse_Literal() + + match NextToken.Type: + TokenType.expr_PStart: + return parse_ParenthesizedExpression() + + TokenType.sym_Identifier: + var identifier = parse_Identifier() + + if identifier.Type == NodeType.sym_Identifier : + return identifier + + var assertStrTmplt = "parse_PrimaryExpression: (Identifier) Unexpected symbol: {value}" + var assertStr = assertStrTmplt.format({"value" : identifier.Type}) + assert(true != true, assertStr) + + TokenType.sym_This : + return parse_ThisExpression() + + TokenType.expr_New : + return parse_NewExpression() + + return parse_ResolvedSymbol() + +# > PrimaryExpression +# Literal +# : NumericLiteral +# | StringLiteral +# | BooleanLiteral +# | NullLiteral +# ; +func parse_Literal(): + match NextToken.Type : + TokenType.literal_Number: + return parse_NumericLiteral() + TokenType.literal_String: + return parse_StringLiteral() + TokenType.literal_BTrue: + return parse_BooleanLiteral(TokenType.literal_BTrue) + TokenType.literal_BFalse: + return parse_BooleanLiteral(TokenType.literal_BFalse) + TokenType.literal_Null: + return parse_NullLiteral() + + assert(false, "parse_Literal: Was not able to detect valid literal type from NextToken") + +# > PrimaryExpression +# ParenthesizedExpression +# : ( Expression ) +# ; +func parse_ParenthesizedExpression(): + eat(TokenType.expr_PStart) + + var expression = parse_Expression() + + eat(TokenType.expr_PEnd) + + return expression + +# > PrimaryExpression +# ThisExpression +# : this +# ; +func parse_ThisExpression(): + eat(TokenType.sym_This) + + var \ + node = PNode.new() + node.Type = NodeType.expr_This + + return node + +# > PrimaryExpression +# NewExpression +# : new MemberExpression Arugments -> new MyNamespace.MyClass(1, 2); +# ; +func parse_NewExpression(): + eat(TokenType.expr_New) + + var memberExp = parse_MemberExpression() + var args = parse_Arguments() + + var \ + node = PNode.new() + node.Type = NodeType.expr_New + node.Value = [ memberExp, args ] + + return node; + +# > Literal +# NumericLiteral +# : Number +# ; +func parse_NumericLiteral(): + var Token = eat(TokenType.literal_Number) + var \ + node = PNode.new() + node.Type = NodeType.literal_Numeric + node.Value = int( Token.Value ) + + return node + +# > Literal +# StringLiteral +# : String +# ; +func parse_StringLiteral(): + var Token = eat(TokenType.literal_String) + var \ + node = PNode.new() + node.Type = NodeType.literal_String + node.Value = Token.Value.substr( 1, Token.Value.length() - 2 ) + + return node + + +# > Literal +# BooleanLiteral +# : true +# | false +# ; +func parse_BooleanLiteral(token): + eat(token) + var value + if (TokenType.literal_BTrue == token) : + value = true + elif (TokenType.literal_BFalse == token) : + value = false + + var \ + node = PNode.new() + node.Type = NodeType.literal_Bool + node.Value = value + + return node + +# > Literal +# NullLiteral +# : null +# ; +func parse_NullLiteral(): + eat(TokenType.literal_Null) + + var \ + node = PNode.new() + node.Type = NodeType.literal_Null + node.Value = null + + return node + diff --git a/App/RDP/Scripts/RDP_Viewer.gd b/App/RDP/Scripts/RDP_Viewer.gd new file mode 100644 index 0000000..c03146c --- /dev/null +++ b/App/RDP/Scripts/RDP_Viewer.gd @@ -0,0 +1,56 @@ +extends Panel + + +var Lexer = preload("Lexer.gd").new() +var Parser = preload("Parser.gd").new() + + +onready var Tokens_TOut = get_node("Tokens_TOut") +onready var AST_TOut = get_node("AST_TOut") +onready var FDialog = get_node("Letter_FDialog") +onready var FD_Btn = get_node("ParseLetterFile_Btn") +onready var Back_Btn = get_node("Back_Btn") + + +func tokens_out(text): + Tokens_TOut.insert_text_at_cursor(text) + +func ast_out(text): + AST_TOut.insert_text_at_cursor(text) + +func parse_file(path): + var \ + file = File.new() + file.open(path, File.READ) + + var programDescription = file.get_as_text() + file.close() + + Lexer.init(programDescription) + + for token in Lexer.Tokens : + var string = "[" + token.Type + "] " + token.Value + "\n" + tokens_out( string ) + + var ast = Parser.parse(Lexer) + var json = JSON.print(ast.to_Dictionary(), '\t') + + ast_out(json + "\n") + ast_out("Finished Parsing!\n") + +func fd_btn_pressed(): + FDialog.popup() + +func fdialog_FSelected(path): + Tokens_TOut.text = "" + AST_TOut.text = "" + parse_file(path) + +func backBtn_pressed(): + queue_free() + +# Called when the node enters the scene tree for the first time. +func _ready(): + FDialog.connect("file_selected", self, "fdialog_FSelected") + FD_Btn.connect("pressed", self, "fd_btn_pressed") + Back_Btn.connect("pressed", self, "backBtn_pressed") diff --git a/App/RegM/RegM_Viewer.tscn b/App/RegM/RegM_Viewer.tscn new file mode 100644 index 0000000..34952f3 --- /dev/null +++ b/App/RegM/RegM_Viewer.tscn @@ -0,0 +1,5 @@ +[gd_scene format=2] + +[node name="RegM_Panel" type="Panel"] +anchor_right = 1.0 +anchor_bottom = 1.0 diff --git a/App/Scenes/CourseDirectory.tscn b/App/Scenes/CourseDirectory.tscn new file mode 100644 index 0000000..a442f1c --- /dev/null +++ b/App/Scenes/CourseDirectory.tscn @@ -0,0 +1,49 @@ +[gd_scene load_steps=5 format=2] + +[ext_resource path="res://Scripts/CourseDirectory.gd" type="Script" id=1] +[ext_resource path="res://Assets/Branding/RDP_Class_cover_small.png" type="Texture" id=2] +[ext_resource path="res://Assets/Branding/RegM_Class_cover_small.png" type="Texture" id=3] +[ext_resource path="res://Assets/Styles/EditorTheme.tres" type="Theme" id=4] + +[node name="Panel" type="Panel"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 1 ) + +[node name="HBox" type="HBoxContainer" parent="."] +anchor_left = 0.15 +anchor_top = 0.25 +anchor_right = 0.85 +anchor_bottom = 0.75 +alignment = 1 + +[node name="RDP_Btn" type="Button" parent="HBox"] +margin_left = 84.0 +margin_right = 339.0 +margin_bottom = 150.0 +rect_min_size = Vector2( 255, 150 ) +size_flags_horizontal = 0 +size_flags_vertical = 0 +theme = ExtResource( 4 ) +icon = ExtResource( 2 ) +icon_align = 1 +expand_icon = true + +[node name="VSeparator" type="VSeparator" parent="HBox"] +margin_left = 343.0 +margin_right = 373.0 +margin_bottom = 300.0 +theme = ExtResource( 4 ) +custom_constants/separation = 30 + +[node name="RegM_Btn" type="Button" parent="HBox"] +margin_left = 377.0 +margin_right = 632.0 +margin_bottom = 150.0 +rect_min_size = Vector2( 255, 150 ) +size_flags_horizontal = 0 +size_flags_vertical = 0 +theme = ExtResource( 4 ) +icon = ExtResource( 3 ) +icon_align = 1 +expand_icon = true diff --git a/App/Scripts/CourseDirectory.gd b/App/Scripts/CourseDirectory.gd new file mode 100644 index 0000000..b5de8d2 --- /dev/null +++ b/App/Scripts/CourseDirectory.gd @@ -0,0 +1,21 @@ +extends Panel + + +onready var RDP_Viewer = load("res://RDP/RDP_Viewer.tscn") +onready var RegM_Viewer = load("res://RegM/RegM_Viewer.tscn") + +onready var RDP_Btn = get_node("HBox/RDP_Btn") +onready var RegM_Btn = get_node("HBox/RegM_Btn") + + +func rdp_pressed(): + add_child( RDP_Viewer.instance() ) + +func regM_pressed(): + add_child( RegM_Viewer.instance() ) + + +# Called when the node enters the scene tree for the first time. +func _ready(): + RDP_Btn.connect("pressed", self, "rdp_pressed") + RegM_Btn.connect("pressed", self, "regM_pressed") diff --git a/Editor/default_env.tres b/App/default_env.tres similarity index 100% rename from Editor/default_env.tres rename to App/default_env.tres diff --git a/Editor/icon.png b/App/icon.png similarity index 100% rename from Editor/icon.png rename to App/icon.png diff --git a/Editor/icon.png.import b/App/icon.png.import similarity index 100% rename from Editor/icon.png.import rename to App/icon.png.import diff --git a/Editor/project.godot b/App/project.godot similarity index 78% rename from Editor/project.godot rename to App/project.godot index 78a7196..aea8988 100644 --- a/Editor/project.godot +++ b/App/project.godot @@ -8,17 +8,25 @@ config_version=4 +_global_script_classes=[ { +"base": "Object", +"class": "Lexer", +"language": "GDScript", +"path": "res://RDP/Scripts/Lexer.gd" +} ] +_global_script_class_icons={ +"Lexer": "" +} + [application] config/name="Parser" run/main_scene="res://Persistent.tscn" -boot_splash/image="res://Assets/Branding/RDP_Class_cover_small.png" config/icon="res://Assets/Branding/RDP_Class_cover_small.png" [autoload] -GScene="*res://Lectures/AST_Viewer.tscn" -GScript="*res://Lectures/Lecture.18.gd" +GScene="*res://Scenes/CourseDirectory.tscn" [gui] diff --git a/Bootstrap_LangStudies.Windows.bat b/Bootstrap_LangStudies.Windows.bat index a84d58d..d5ce113 100644 --- a/Bootstrap_LangStudies.Windows.bat +++ b/Bootstrap_LangStudies.Windows.bat @@ -30,7 +30,7 @@ if not exist Engine\gd\bin\godot.windows.opt.tools.64.exe ( ) timeout 10 -start Engine\gd\bin\godot.windows.opt.tools.64.exe -e Editor/project.godot +start Engine\gd\bin\godot.windows.opt.tools.64.exe -e App/project.godot timeout 30 taskkill /f /im godot.windows.opt.tools.64.exe diff --git a/Readme.md b/Readme.md index 0e96df9..f828ea0 100644 --- a/Readme.md +++ b/Readme.md @@ -4,4 +4,4 @@ A set of material done while following [Dmitry Soshnikov's](https://t.co/UL7NQyykPu) courses Currently I'm in the process of completing -![Building a parser from scratch](https://i.imgur.com/rEzWwGs.png) \ No newline at end of file +![Automata: RegExp Machines](https://i.imgur.com/NWwBjhN.png) \ No newline at end of file diff --git a/build_project.bat b/build_project.bat index 0ecd702..6ca98c3 100644 --- a/build_project.bat +++ b/build_project.bat @@ -12,4 +12,4 @@ cd Builds mkdir %SUBFILENAME% cd ..\Engine\gd\bin -godot.windows.opt.64.exe --export "Windows Desktop" "..\Builds\%SUBFILENAME%\LangStudies.exe" --path "..\..\..\Editor" \ No newline at end of file +godot.windows.opt.64.exe --export "Windows Desktop" "..\Builds\%SUBFILENAME%\LangStudies.exe" --path "..\..\..\App" \ No newline at end of file diff --git a/editor.bat b/editor.bat index c79cceb..61a3a4f 100644 --- a/editor.bat +++ b/editor.bat @@ -1,3 +1,3 @@ -start Engine\gd\bin\godot.windows.opt.tools.64.exe -e Editor/project.godot +start Engine\gd\bin\godot.windows.opt.tools.64.exe -e App/project.godot diff --git a/game.debug.bat b/game.debug.bat index be6df30..12d1817 100644 --- a/game.debug.bat +++ b/game.debug.bat @@ -1,3 +1,3 @@ -start Engine\gd\bin\godot.windows.tools.64.exe --path Editor/ +start Engine\gd\bin\godot.windows.tools.64.exe --path App/ diff --git a/game.release.bat b/game.release.bat index b16d032..62ba422 100644 --- a/game.release.bat +++ b/game.release.bat @@ -1,3 +1,3 @@ -start Engine\gd\bin\godot.windows.opt.64.exe --path Editor/ +start Engine\gd\bin\godot.windows.opt.64.exe --path App/ diff --git a/game.release_debug.bat b/game.release_debug.bat index f6adf09..aceb4cb 100644 --- a/game.release_debug.bat +++ b/game.release_debug.bat @@ -1,3 +1,3 @@ -start Engine\gd\bin\godot.windows.opt.tools.64.exe --path Editor/ +start Engine\gd\bin\godot.windows.opt.tools.64.exe --path App/ diff --git a/logs/godot.log b/logs/godot.log deleted file mode 100644 index 442a41c..0000000 --- a/logs/godot.log +++ /dev/null @@ -1,12 +0,0 @@ -Godot Engine v3.3.4.stable.official.faf3f883d - https://godotengine.org -OpenGL ES 3.0 Renderer: NVIDIA GeForce GTX 1080/PCIe/SSE2 -OpenGL ES Batching: ON - -**ERROR**: Condition "err" is true. Returned: err - At: modules/gdscript/gdscript.cpp:815:load_source_code() - Condition "err" is true. Returned: err -**ERROR**: Cannot load source code from file 'C:/Projects/Study/LangStudies/Editor/Lecture.3.gd'. - At: modules/gdscript/gdscript.cpp:2241:load() - Condition "err != OK" is true. Returned: RES() -**ERROR**: Failed loading resource: C:/Projects/Study/LangStudies/Editor/Lecture.3.gd. Make sure resources have been imported by opening the project in the editor at least once. - At: core/io/resource_loader.cpp:282:_load() - Condition "found" is true. Returned: RES() -**ERROR**: Can't load script: C:/Projects/Study/LangStudies/Editor/Lecture.3.gd - At: main/main.cpp:1658:start() - Condition "script_res.is_null()" is true. Returned: false diff --git a/logs/godot_2022-07-07_21.35.04.log b/logs/godot_2022-07-07_21.35.04.log deleted file mode 100644 index 4cda1f2..0000000 --- a/logs/godot_2022-07-07_21.35.04.log +++ /dev/null @@ -1,7 +0,0 @@ -Godot Engine v3.3.4.stable.official.faf3f883d - https://godotengine.org -OpenGL ES 3.0 Renderer: NVIDIA GeForce GTX 1080/PCIe/SSE2 -OpenGL ES Batching: ON - -Project is missing: C:/Projects/Study/Parsing/Editor/project.godot -**ERROR**: Condition "default_certs != __null" is true. - At: modules/mbedtls/crypto_mbedtls.cpp:201:load_default_certificates() - Condition "default_certs != __null" is true. diff --git a/logs/godot_2022-07-07_21.35.40.log b/logs/godot_2022-07-07_21.35.40.log deleted file mode 100644 index 442a41c..0000000 --- a/logs/godot_2022-07-07_21.35.40.log +++ /dev/null @@ -1,12 +0,0 @@ -Godot Engine v3.3.4.stable.official.faf3f883d - https://godotengine.org -OpenGL ES 3.0 Renderer: NVIDIA GeForce GTX 1080/PCIe/SSE2 -OpenGL ES Batching: ON - -**ERROR**: Condition "err" is true. Returned: err - At: modules/gdscript/gdscript.cpp:815:load_source_code() - Condition "err" is true. Returned: err -**ERROR**: Cannot load source code from file 'C:/Projects/Study/LangStudies/Editor/Lecture.3.gd'. - At: modules/gdscript/gdscript.cpp:2241:load() - Condition "err != OK" is true. Returned: RES() -**ERROR**: Failed loading resource: C:/Projects/Study/LangStudies/Editor/Lecture.3.gd. Make sure resources have been imported by opening the project in the editor at least once. - At: core/io/resource_loader.cpp:282:_load() - Condition "found" is true. Returned: RES() -**ERROR**: Can't load script: C:/Projects/Study/LangStudies/Editor/Lecture.3.gd - At: main/main.cpp:1658:start() - Condition "script_res.is_null()" is true. Returned: false