func (lit DcpuLitteral) Code(prog DcpuProgram) []dcpu.Word { value := dcpu.Word(lit) if lit.isEmbeded() { // embeded litteral return []dcpu.Word{value + 0x20} } // else next word return []dcpu.Word{0x1f, value} }
func (reg DcpuRegister) Code(prog DcpuProgram) []dcpu.Word { registers := []DcpuRegister{"A", "B", "C", "X", "Y", "Z", "I", "J"} for i, r := range registers { if reg == r { return []dcpu.Word{dcpu.Word(i)} } } panic(fmt.Sprintf("Couldn't find register: %s", reg)) }
func yyParse(yylex yyLexer) int { var yyn int var yylval yySymType var yyVAL yySymType yyS := make([]yySymType, yyMaxDepth) Nerrs := 0 /* number of errors */ Errflag := 0 /* error recovery flag */ yystate := 0 yychar := -1 yyp := -1 goto yystack ret0: return 0 ret1: return 1 yystack: /* put a state and value onto the stack */ if yyDebug >= 4 { fmt.Printf("char %v in %v\n", yyTokname(yychar), yyStatname(yystate)) } yyp++ if yyp >= len(yyS) { nyys := make([]yySymType, len(yyS)*2) copy(nyys, yyS) yyS = nyys } yyS[yyp] = yyVAL yyS[yyp].yys = yystate yynewstate: yyn = yyPact[yystate] if yyn <= yyFlag { goto yydefault /* simple state */ } if yychar < 0 { yychar = yylex1(yylex, &yylval) } yyn += yychar if yyn < 0 || yyn >= yyLast { goto yydefault } yyn = yyAct[yyn] if yyChk[yyn] == yychar { /* valid shift */ yychar = -1 yyVAL = yylval yystate = yyn if Errflag > 0 { Errflag-- } goto yystack } yydefault: /* default state action */ yyn = yyDef[yystate] if yyn == -2 { if yychar < 0 { yychar = yylex1(yylex, &yylval) } /* look through exception table */ xi := 0 for { if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate { break } xi += 2 } for xi += 2; ; xi += 2 { yyn = yyExca[xi+0] if yyn < 0 || yyn == yychar { break } } yyn = yyExca[xi+1] if yyn < 0 { goto ret0 } } if yyn == 0 { /* error ... attempt to resume parsing */ switch Errflag { case 0: /* brand new error */ yylex.Error("syntax error") Nerrs++ if yyDebug >= 1 { fmt.Printf("%s", yyStatname(yystate)) fmt.Printf("saw %s\n", yyTokname(yychar)) } fallthrough case 1, 2: /* incompletely recovered error ... try again */ Errflag = 3 /* find a state where "error" is a legal shift action */ for yyp >= 0 { yyn = yyPact[yyS[yyp].yys] + yyErrCode if yyn >= 0 && yyn < yyLast { yystate = yyAct[yyn] /* simulate a shift of "error" */ if yyChk[yystate] == yyErrCode { goto yystack } } /* the current p has no shift on "error", pop stack */ if yyDebug >= 2 { fmt.Printf("error recovery pops state %d\n", yyS[yyp].yys) } yyp-- } /* there is no state on the stack with an error shift ... abort */ goto ret1 case 3: /* no shift yet; clobber input char */ if yyDebug >= 2 { fmt.Printf("error recovery discards %s\n", yyTokname(yychar)) } if yychar == yyEofCode { goto ret1 } yychar = -1 goto yynewstate /* try again in the same state */ } } /* reduction by production yyn */ if yyDebug >= 2 { fmt.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate)) } yynt := yyn yypt := yyp _ = yypt // guard against "declared and not used" yyp -= yyR2[yyn] yyVAL = yyS[yyp+1] /* consult goto table to find next state */ yyn = yyR1[yyn] yyg := yyPgo[yyn] yyj := yyg + yyS[yyp].yys + 1 if yyj >= yyLast { yystate = yyAct[yyg] } else { yystate = yyAct[yyj] if yyChk[yystate] != -yyn { yystate = yyAct[yyg] } } // dummy call; replaced with literal code switch yynt { case 1: //line dcpuAssembly.y:49 { if lexer, ok := yylex.(*DCPULex); ok { lexer.hack.ast = DcpuProgram{expressions: yyS[yypt-0].exprlst} } else { panic(fmt.Sprintf("unexected lexer type, got: %s", reflect.TypeOf(lexer))) } } case 2: //line dcpuAssembly.y:58 { if lexer, ok := yylex.(*DCPULex); ok { var expr DcpuExpression = yyS[yypt-1].expr var list []DcpuExpression = yyS[yypt-0].exprlst if _, ok := expr.(DcpuDataExpression); ok { // data expression should be appended *at the // end of the code segment* yyVAL.exprlst = append(list, expr) } else { // here, since the regular expression solving will // match the last expressions first, we must append at // the begginning of the slice ;p yyVAL.exprlst = append([]DcpuExpression{expr}, list...) } } else { panic(fmt.Sprintf("unexected lexer type, got: %s", reflect.TypeOf(lexer))) } } case 3: //line dcpuAssembly.y:81 { yyVAL.exprlst = []DcpuExpression{} } case 4: //line dcpuAssembly.y:86 { yyVAL.expr = yyS[yypt-0].nexpr } case 5: //line dcpuAssembly.y:91 { yyVAL.expr = yyS[yypt-0].dexpr } case 6: //line dcpuAssembly.y:97 { expr := new(DcpuNormalExpression) expr.inst = yyS[yypt-3].inst expr.a = yyS[yypt-2].operand expr.b = yyS[yypt-0].operand expr.label = "" yyVAL.nexpr = *expr } case 7: //line dcpuAssembly.y:107 { expr := new(DcpuNormalExpression) expr.inst = yyS[yypt-3].inst expr.a = yyS[yypt-2].operand expr.b = yyS[yypt-0].operand expr.label = yyS[yypt-4].lab yyVAL.nexpr = *expr } case 8: //line dcpuAssembly.y:117 { yyVAL.operand = DcpuRegister(yyS[yypt-0].reg) } case 9: //line dcpuAssembly.y:122 { yyVAL.operand = DcpuSpecialRegister(yyS[yypt-0].specialReg) } case 10: //line dcpuAssembly.y:127 { yyVAL.operand = yyS[yypt-0].ref } case 11: //line dcpuAssembly.y:131 { yyVAL.operand = DcpuLitteral(yyS[yypt-0].lit) } case 12: //line dcpuAssembly.y:135 { yyVAL.operand = DcpuLabel(yyS[yypt-0].lab) } case 13: //line dcpuAssembly.y:140 { yyVAL.ref = yyS[yypt-1].ref } case 14: //line dcpuAssembly.y:145 { reference := new(DcpuReference) reference.ref = yyS[yypt-0].reg yyVAL.ref = *reference } case 15: //line dcpuAssembly.y:151 { reference := new(DcpuReference) reference.ref = yyS[yypt-0].sum yyVAL.ref = *reference } case 16: //line dcpuAssembly.y:157 { reference := new(DcpuReference) reference.ref = yyS[yypt-0].lit yyVAL.ref = *reference } case 17: //line dcpuAssembly.y:163 { reference := new(DcpuReference) reference.ref = yyS[yypt-0].lab yyVAL.ref = *reference } case 18: //line dcpuAssembly.y:170 { sum := new(DcpuSum) sum.lit = yyS[yypt-2].lit sum.reg = yyS[yypt-0].reg yyVAL.sum = *sum } case 19: //line dcpuAssembly.y:178 { expr := new(DcpuDataExpression) expr.data = []dcpu.Word{dcpu.Word(yyS[yypt-0].lit)} expr.label = yyS[yypt-2].lab yyVAL.dexpr = *expr } case 20: //line dcpuAssembly.y:186 { expr := new(DcpuDataExpression) //expr.data = []dcpu.Word([]byte(string(label))) str := yyS[yypt-0].str data := []dcpu.Word{} for _, char := range str { data = append(data, dcpu.Word(char)) } expr.data = data expr.label = yyS[yypt-2].lab yyVAL.dexpr = *expr } } goto yystack /* stack new state and value */ }
func (sum DcpuSum) ReferenceCode(prog DcpuProgram) []dcpu.Word { // registers Code always returns 1 word return []dcpu.Word{sum.reg.Code(prog)[0] + 0x10, dcpu.Word(sum.lit)} }
func (lit DcpuLitteral) ReferenceCode(prog DcpuProgram) []dcpu.Word { return []dcpu.Word{0x1e, dcpu.Word(lit)} }