From 1d9ad824a6026342e770caa91fab044d3311ec30 Mon Sep 17 00:00:00 2001 From: RochesterX Date: Sat, 31 Jan 2026 19:51:05 -0500 Subject: [PATCH] Fixed parsing bug 1, just empty FactorSequence left --- Sources/rxcc/rxcc.swift | 155 ++++++++++++++++++++++++++-------------- a.out | Bin 15704 -> 16840 bytes hard.c | 3 + hard.s | 24 +++++++ test | 4 +- test.c | 2 +- test.s | 8 +++ test2.c | 2 +- test2.s | 6 ++ test2s | 0 10 files changed, 145 insertions(+), 59 deletions(-) create mode 100644 hard.c create mode 100644 hard.s create mode 100644 test2s diff --git a/Sources/rxcc/rxcc.swift b/Sources/rxcc/rxcc.swift index 6a9a458..a941430 100644 --- a/Sources/rxcc/rxcc.swift +++ b/Sources/rxcc/rxcc.swift @@ -348,29 +348,6 @@ func lex(string: String) -> [Substring] { return [] } -func parse(lexed: [Substring]) -> String { - var tokens: [Token] = [Token]() - for token: Substring in lexed { - let tokenType: TokenType = categorizeToken(token: token) - tokens.append(Token(content: token, type: tokenType)) - } - tokens = tokens.reversed() - - let abstractSyntaxTree = SyntaxTreeNode(.Root) - - if validateConstruct(program.variants[.SingleFunction]!, tokens: &tokens, node: abstractSyntaxTree) != .Invalid { - print("Success") - print(abstractSyntaxTree.text()) - print("Assembly:") - let assembly: String = generateOutput(abstractSyntaxTree) - print(assembly) - return assembly - } - - print("Distinct lack of success") - return "" -} - func generateOutput(_ node: SyntaxTreeNode) -> String { var text: String = "" switch node.variant { @@ -387,13 +364,51 @@ func generateOutput(_ node: SyntaxTreeNode) -> String { break case .FactorSequence: - for child in node.children { + var operation: ConstructVariant = .Error + let count = node.children.count + if count == 0 { + print("ERROR: FactorSequence with no children") + break + } + for i in 0...count - 1 { + let child: SyntaxTreeNode = node.children[i] + + // Operation + if i % 2 == 1 { + operation = child.variant + continue + } + text += generateOutput(child) + + switch operation { + case .Multiplication: + text += " pop %ecx\n" + text += " imul %ecx, %eax\n" + + default: + if i != 0 { + print("Unknown operation \"\(operation)\" in FactorSequence") + } + break + } + + if i != node.children.count - 1 { + text += " push %eax\n" + } } break +/* + + push %eax ; save value of e1 on the stack + + pop %ecx ; pop e1 from the stack into ecx + addl %ecx, %eax ; add e1 to e2, save results in eax +*/ + case .Integer: - text += " .globl \(node.value)\n\(node.value):\n" + text += " .globl \(node.value)\n\(node.value):\n" for child in node.children { text += generateOutput(child) } @@ -444,13 +459,36 @@ func generateOutput(_ node: SyntaxTreeNode) -> String { return text } +func parse(lexed: [Substring]) -> String { + var tokens: [Token] = [Token]() + for token: Substring in lexed { + let tokenType: TokenType = categorizeToken(token: token) + tokens.append(Token(content: token, type: tokenType)) + } + tokens = tokens.reversed() + + let abstractSyntaxTree = SyntaxTreeNode(.Root) + + if validateConstruct(program.variants[.SingleFunction]!, tokens: &tokens, node: abstractSyntaxTree, loopingEnabled: false) != .Invalid { + print("Success") + print(abstractSyntaxTree.text()) + print("Assembly:") + let assembly: String = generateOutput(abstractSyntaxTree) + print(assembly) + return assembly + } + + print("Distinct lack of success") + return "" +} + enum Validity { case Valid case Invalid case Break } -func validateConstruct(_ construct: Construct, tokens: inout [Token], node: SyntaxTreeNode) -> Validity { +func validateConstruct(_ construct: Construct, tokens: inout [Token], node: SyntaxTreeNode, loopingEnabled: Bool) -> Validity { var indent: String { var count: Int = 0 var child: SyntaxTreeNode = node @@ -461,7 +499,7 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt return String(repeating: " ", count: count) } - var loop: Bool = false + var loop: Bool = loopingEnabled repeat { for element in construct { switch element { @@ -471,18 +509,23 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt var valid: Validity = .Invalid var validVariant: ConstructVariant = .Error let tokenBackup: [Token] = tokens - for key in constructDefinitions[type]!.keys { - let childNode = node.addChild(value: key) - print("\(indent)Testing variant \(key) (Loop = \(loop))") - valid = validateConstruct(constructDefinitions[type]![key]!, tokens: &tokens, node: childNode) + for variant in constructDefinitions[type]!.keys { + let childNode = node.addChild(value: variant) + var loopable = false + if variant == .FactorSequence || variant == .TermSequence { + loopable = true + } + + print("\(indent)Testing variant \(variant) (Loop = \(loop)) (Loopable = \(loopable))") + valid = validateConstruct(constructDefinitions[type]![variant]!, tokens: &tokens, node: childNode, loopingEnabled: loopable) if valid == .Invalid { - print("\(indent)Fail") + print("\(indent)Fail (no valid variants)\n") tokens = tokenBackup _ = node.popLastChild() continue } - print("\(indent)Success") - validVariant = key + print("\(indent)Success (variant \"\(variant)\")\n") + validVariant = variant break } @@ -490,29 +533,31 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt - // Factor looping nonsense - if type == .Factor { - let nextToken: Token = tokens[tokens.count - 1] - if nextToken.type == .MULTIPLICATION || nextToken.type == .DIVISION { - print("\(indent)Looping due to factor") - loop = true - } else { - print("\(indent)Breaking out of factor loop") - loop = false - return .Break + if loopingEnabled { + // Factor looping nonsense + if type == .Factor { + let nextToken: Token = tokens[tokens.count - 1] + if nextToken.type == .MULTIPLICATION || nextToken.type == .DIVISION { + print("\(indent)Looping due to factor") + loop = true + } else { + print("\(indent)Breaking out of factor loop") + loop = false + return .Break + } } - } - // Term looping nonsense - else if type == .Term { - let nextToken: Token = tokens[tokens.count - 1] - if nextToken.type == .ADDITION || nextToken.type == .NEGATION { - print("\(indent)Looping due to term") - loop = true - } else { - print("\(indent)Breaking out of term loop") - loop = false - return .Break + // Term looping nonsense + else if type == .Term { + let nextToken: Token = tokens[tokens.count - 1] + if nextToken.type == .ADDITION || nextToken.type == .NEGATION { + print("\(indent)Looping due to term") + loop = true + } else { + print("\(indent)Breaking out of term loop") + loop = false + return .Break + } } } diff --git a/a.out b/a.out index ffc6a385fd7cc3725b2124653f7bfc19b0c0ea6d..6397d0db751d81d781a966bead027ad9b43a8f7b 100755 GIT binary patch literal 16840 zcmeI4&r4KM6vyw3V!dZDbbKey?pKlHEK}ruMB;R@4^$4$?=#{Xg z0v$js{v@mcy9?S5%@jEo{Ts zPv^)`(&`H~1~FH>+o?VTBmHBhQafQQ-B@^u?1#$vw29u%kcfUS8z(E=SW6QB49<2(+lN-x9YH9~O-51l= zuyrw&v~yNccRjoM^hLP;{r8?Z-`B;(OWw9{?#9^5u`3fxZ*Ml; tsCxXb=RLKD_Y90wwv3iv>%8}TDQ`J=zj*3R)%Bl04xah=&2Ku(`~uc#xM~0Z literal 15704 zcmeHOU2Gjk6`p(TG)|htH*Ou=IwDIHRgHu#ULUL+n(b(yrF`uI($` zAM4&V*acLp0Tio>2ofL=4^-j>i3bGqp;dWs6jbO7btRAxPvNH`AfT@JQ3}G#IkV?m zuQ%6#c&LP!vF?6zzB%X2?3vl!S?|oVg^96jCZmwr)Z>aJD;F_&Dfq~cWC-%=F}075 z2UV}SkK}gEMdkSjs5DBswyoG9JkxCVqLiocpy&b7LPoaRE_HB&C;^q62ixu70+G`= zAQb>n9@l5FF(peMWBj6sz@!~FC1*zpxyQGn%0_aBAnaIVJ4@^=u>-y!?F1s8925Rs zl6a;uPi36)`bhB+gxw9XOXCsI1F}9R*aemrRT_nk!v(v^H-i%A)9r(tkKEnU&P!s~ zE{@ZPaRNkrA0|5)65{z^1BSNS7L zo38leYqnaiiFY?rZK-MO1Qpp zUFG&ie2-ke;8(?AM?NYC4|(-W#PgU<_Ti5bd^S?i$F&46m$2r4mf&$MaKY^aukVLi z+Z;>;Oax2>Oax2>Oax2>Oa%U4BJiiq_x{bf`uh&&`5iZpDdl{2HOPi*&eb1u+|nW7 z@_|2$ue|ZJv+_&l>aW)?O%(=K2VQfopZ+;1gx#Mct3S`!orgZ7^@)F({aoMiU4~P4 zgKl#Dw7A|C-tIiK%!;=JNqaQ=znvxBE9B#)E3b#)Q@7$6#ZloiFv&!~M8HJAM8HJAM8HJAM8HJAM8HJA zM8HJgeA_?CiKfAEub+ zZ>_iA3d2WOVRWbdvc(+R-y}cxGe5j9_qpuI-uuSLkY!5zJ&Kk2`xbxWm45w8S5c? zMaH||!y;o{B-ZPq{4X0}omJLkF(cL}F3ZayuZ!fgF6Fx;QC$<%@0^t9_gPNe5yZ!x zl5@l{>RlC{7J2Ff`@e@#dx+Gk8zT3JJ$)(G?M0mEwO7j>QvQy}$+ekM#k&evKfYb1 zSbutMWaI?B^h6$uHGm7a*F5wHLyO$EA&4^nT&dm%H<;l{quz8yA;M>RI1dcDZ_p+ z{=u(k{rw8#8T>aX)2jX7-iCi!`{`8k7G+YYm7gDyPDVYT(*3rkZTG2mYpauAY5i_> zN7nbE^c~8yTGxGm0%Acafy0_Vpj19VQg)E|oH`K46Q!q!@5=5`xcu8!zAH<2snobtlf_0bVApAdx;I^R18-Il zF->dOYm>xoE@yXxs$1j*?M+fG)!o@jecG$IrJ&wuy57Q~D%Pv>6+iGxc7JOPUP@nf zy+*@Za{XG+SW+_$uj;#{g=%$)OcIhyn!y&;z;6b2k=y3iO58Hn9lJbyzTg%vjJmX- ze)OXkhR=_W5KZ?Cx8O*rGkRIM=O!+m9iDJ6j*U$grrfFFvl9ifNU!(LV_E;dTgva3 zyuefXY{&}>(Yk&Twl4B_OU=4F=haHQ0bu+hX_d+~ccJN*6a|0|?sT&$wzA`ZHVxp6 zcsD`IEdpEjCB)6<-3U5vO4-e&YT!*128{^kkgL@L-=3{4*z=A0yx$0xlpRyk3uW5N zQ7$RFT%!#P^GYkudCfUxmzHYeG{T?}m3-W9G|Tnc7Qv;mhF|g6fc=yMWe5Hu9l7_Z ztgfSH`*YIYb0xBXB#jw9JKo15QQJquAhJiEoO{)Bk!r4!XFAyP70N`eDX7Y((O9KH zmb?W1t31ye_*tD5YwQmK=7k5~IS!e(PbKYd$O9O71d4*VuYew=3|+c${oCzNgFfpf z(>Mu#rDs3dzb5qqG4GLSLcAXfJ|-!{_afM@i#_m$C}N)o&L8uZC#jrGV2}9|@S4~I z((Nx&0ncqOiuiA1rdMHuTUm={bBwGw4f-6c7uM6 zGW+N!!#u}3|ymvBH-ZA369>M;-d^z{e(Bx3Bw#_UfVI?^zHpX6%