예제 #1
0
파일: asm.go 프로젝트: DanB91/dcpu
// buildBlock builds a block expression.
func (a *assembler) buildBlock(argv *[]cpu.Word, symbols *[]parser.Node, b *parser.Block) (val cpu.Word, err error) {
	nodes := b.Children()

	switch len(nodes) {
	case 1:
		switch tt := nodes[0].(type) {
		case *parser.Name:
			if reg, ok := registers[tt.Data]; ok {
				return reg + 0x08, nil
			}

			if addr, ok := a.labels[tt.Data]; ok {
				*symbols = append(*symbols, tt)
				*argv = append(*argv, addr)
				return 0x1e, nil
			}

			a.refs[cpu.Word(len(a.code)+1+len(*argv))] = tt
			*symbols = append(*symbols, tt)
			*argv = append(*argv, 0)
			return 0x1e, nil

		case parser.NumericNode:
			num, err := tt.Parse()
			if err != nil {
				return 0, err
			}

			*symbols = append(*symbols, tt)
			*argv = append(*argv, num)
			return 0x1e, nil

		default:
			return 0, NewBuildError(
				a.ast.Files[tt.File()], tt.Line(), tt.Col(),
				"Unexpected node %T. Want Name, Number or Block.", tt,
			)
		}

	case 3:
		var va, vb cpu.Word

		if va, err = a.buildBlockOperand(argv, symbols, nodes[0]); err != nil {
			return
		}

		if vb, err = a.buildBlockOperand(argv, symbols, nodes[2]); err != nil {
			return
		}

		if va != 0 {
			return va, nil
		}

		return vb, nil

	default:
		err = NewBuildError(
			a.ast.Files[b.File()], b.Line(), b.Col(),
			"Unexpected node count. Want 1 or 3. Got %d", len(nodes))
	}

	return
}
예제 #2
0
파일: sourcewriter.go 프로젝트: DanB91/dcpu
func (sw *SourceWriter) writeBlock(n *parser.Block) {
	sw.w.Write(lbrack)
	sw.writeList(n.Children())
	sw.w.Write(rbrack)
}