예제 #1
0
        def operate_on_content_of_ptr(ptr_addr, offset):
            if offset == 0:
                return ASM(f'''
            // load the pointer value
            @{ptr_addr}

            // dereference the pointer
            A=M

            // operate on content-of pointer
            M=%COMP%
            ''')
            else:
                return ASM(f'''
            // load the pointer value into D
            @{ptr_addr}
            D=M

            // load the offset into A
            @{offset}

            // calculate the new pointer value
            // and save into D
            A=A+D

            // dereference the pointer
            A=M

            // operate on content-of pointer
            M=%COMP%
            ''')
예제 #2
0
    def resolve(self, known_symbols=None):
        if int(self.args[1]) > 0:
            function_init = f'''
        ({self.label_in_namespace})
        $load_sp
      '''

            local_init = '''
        // set the current top of stack to 0
        M=0

        // increment top of stack
        A=A+1
      ''' * int(self.args[1])

            sp_prep = '''
        // need this so SP now points to the next available
        // slot after local vars
        $save_sp
      '''
            return ASM(function_init + local_init + sp_prep)
        else:
            # when we use no local vars we don't need any init, just a label
            return ASM(f'''
        ({self.label_in_namespace})
      ''')
예제 #3
0
 def set_ram(addr, value):
     asm = ASM(f'''
 // setup {addr}
 @{value}
 D=A
 @{addr}
 M=D
 ''')
     self.asm_output += asm.to_list(indent=4)
예제 #4
0
        def pop_into_ptr(ptr_addr, offset):
            if offset == 0:
                return ASM(f'''
            $load_sp
            A=A-1

            // load top-of-stack value into D
            D=M

            // load the pointer value
            @{ptr_addr}

            // dereference the pointer
            A=M

            // write D into destination
            M=D

            $dec_sp
            ''')
            else:
                return ASM(f'''
            // load the pointer value into D
            @{ptr_addr}
            D=M

            // load the offset into A
            @{offset}

            // calculate the new pointer value
            // and save into D
            D=A+D

            // save the value into T0
            @T0
            M=D

            $load_sp
            A=A-1

            // load top-of-stack value into D
            D=M

            // load pointer value
            @T0

            // dereference the pointer
            A=M

            // write D into destination
            M=D

            $dec_sp
            ''')
예제 #5
0
def test_compat():
    ASM.set_compat(True)
    asm = EQ_Operation(compat=True).resolve()
    Assembler(compat=True).assemble(str(asm))

    try:
        ASM.set_compat(False)
        asm = EQ_Operation().resolve()
        Assembler(compat=True).assemble(str(asm))
    except:
        pass
    else:
        assert False, 'Should have failed'
예제 #6
0
def test_add():
    asm = ADD_Operation().resolve()
    print(asm)
    expected = ASM('''
      // MACRO=LOAD_SP
      @SP
      A=M
      // MACRO_END
      // pop y into D
      A=A-1
      D=M
      // pop x into M
      A=A-1
      // do the operation
      M=M+D
      // MACRO=DEC_SP
      @SP
      M=M-1
      // MACRO_END
        ''')
    assert str(asm) == str(expected)

    # make sure it output valid assembly
    assembler = Assembler()
    assembler.assemble(str(asm))
예제 #7
0
        def operate_on_memory(mem_addr):
            return ASM(f'''
          // load the memory address
          @{mem_addr}

          // write D into destination
          M=%COMP%
          ''')
예제 #8
0
    def resolve(self, known_symbols=None):
        # see comment in LABEL_Operation.resolve
        return ASM(f'''
        // load jump destination into A
        @{self.label_in_namespace}

        // unconditional jump
        0;JEQ
        ''')
예제 #9
0
        def push_content_of_ptr(ptr_addr, offset):
            if offset == 0:
                return ASM(f'''
            // load the pointer value
            @{ptr_addr}

            // dereference the pointer
            A=M

            // save the value into D
            D=M

            $load_sp

            // write value to top of stack
            M=D

            $inc_sp
            ''')
            else:
                return ASM(f'''
            // load the pointer value into D
            @{ptr_addr}
            D=M

            // load the offset into A
            @{offset}

            // calculate the new pointer value
            // and dereference
            A=A+D

            // save the value into D
            D=M

            $load_sp

            // write value to top of stack
            M=D

            $inc_sp
            ''')
예제 #10
0
    def resolve(self, known_symbols=None):
        return ASM('''
        $load_sp

        // pop y into inM
        A=A-1

        // neg
        M=-M

        // no need to update SP b/c
        // the top of the stack is not
        // changed by a pop and push
        ''')
예제 #11
0
        def push_content_of_memory(mem_addr):
            return ASM(f'''
          // load memory address
          @{mem_addr}

          // save the value into D
          D=M

          $load_sp

          // write value to top of stack
          M=D

          $inc_sp
          ''')
예제 #12
0
    def resolve(self, known_symbols=None):
        return ASM('''
        $load_sp

        // pop y into D
        A=A-1
        D=M

        // invert and write result to stack
        M=!D

        // no need to update SP b/c
        // the top of the stack is not
        // changed by a pop and push
        ''')
예제 #13
0
    def resolve(self, known_symbols=None):
        return ASM('''
        $load_sp

        // pop y into D
        A=A-1
        D=M

        // pop x into M
        A=A-1

        // do the operation
        M=M%OP%D

        $dec_sp
        ''')
예제 #14
0
        def pop_into_memory(mem_addr):
            return ASM(f'''
          $load_sp
          A=A-1

          // load top-of-stack value into D
          D=M

          // load the memory address
          @{mem_addr}

          // write D into destination
          M=D

          $dec_sp
          ''')
예제 #15
0
    def resolve(self, known_symbols=None):
        # see comment in LABEL_Operation.resolve
        return ASM(f'''
        $load_sp

        // pop value into D
        A=A-1
        D=M

        // we have to do this now b/c once
        // the jump executes it is too late
        $dec_sp

        // load jump destination
        @{self.label_in_namespace}

        // take a leaf from most languages: true
        // means !0
        D;JNE
        ''')
예제 #16
0
    def resolve(self, known_symbols=None):
        return ASM('''
        $load_sp

        // pop y into D
        A=A-1
        D=M

        // pop x into M
        A=A-1

        // sub
        D=M-D

        // write -1 (=0xFFFF) into M assuming
        // are EQ
        M=-1

        // update stack pointer to point to top
        // of stack
        $dec_sp

        @$_END
        D;%JMP%

        // if we didn't jump then the comparison
        // fail and we write 0 into the top
        // of the stack

        $load_sp
        A=A-1

        // write 0
        M=0

        ($_END)
        ''')
예제 #17
0
    def resolve(self, known_symbols=None):
        self.namespace = NAMESPACE_FILE

        segment, index = self.args
        segment, index = Operation.validate_segment_index(
            segment, index, known_symbols)

        def push_content_of_ptr(ptr_addr, offset):
            if offset == 0:
                return ASM(f'''
            // load the pointer value
            @{ptr_addr}

            // dereference the pointer
            A=M

            // save the value into D
            D=M

            $load_sp

            // write value to top of stack
            M=D

            $inc_sp
            ''')
            else:
                return ASM(f'''
            // load the pointer value into D
            @{ptr_addr}
            D=M

            // load the offset into A
            @{offset}

            // calculate the new pointer value
            // and dereference
            A=A+D

            // save the value into D
            D=M

            $load_sp

            // write value to top of stack
            M=D

            $inc_sp
            ''')

        # this is the sme as push_content_of_ptr but
        # minus the deference step for those segments
        # with fixed addresses
        def push_content_of_memory(mem_addr):
            return ASM(f'''
          // load memory address
          @{mem_addr}

          // save the value into D
          D=M

          $load_sp

          // write value to top of stack
          M=D

          $inc_sp
          ''')

        if segment in VM2ASM.SEGMENT_BASE_ADDR_TABLE:
            ptr_addr = VM2ASM.SEGMENT_BASE_ADDR_TABLE[segment]
            return push_content_of_ptr(ptr_addr, index)

        elif segment == 'temp':
            # b/c temp is fixed we can calculate the pointer address
            # directly
            mem_addr = VM2ASM.TEMP_BASE_ADDRESS + index
            return push_content_of_memory(mem_addr)

        elif segment == 'static':
            # static is special where we don't actually index into anything but auto-allocate into
            # the variable memory address. We leave that job to the assembler
            mem_addr = f'{self.label_in_namespace}.STATIC{index}'
            return push_content_of_memory(mem_addr)

        elif segment == 'pointer':
            # set the addr of this (0) or that (1)
            ptr_name = ['this', 'that'][index]
            mem_addr = VM2ASM.SEGMENT_BASE_ADDR_TABLE[ptr_name]
            return push_content_of_memory(mem_addr)

        elif segment == 'constant':
            return ASM(f'''
          // load {index} into D
          @{index}
          D=A

          // load the stack pointer
          $load_sp

          // write the constant to the top
          // of the stack
          M=D

          $inc_sp
          ''')

        else:
            raise NameError(f'Unknown segment {segment}')
예제 #18
0
def test_unique_labels():
    asm1 = ASM('$_LABEL')

    # we should generate unique asm every time
    assert str(asm1) != str(asm1)
예제 #19
0
 def resolve(self, known_symbols=None):
     # we don't use $ID_ macro here b/c these labels
     # originate from the user and could have scope beyond the
     # assembly emitted for this operation
     return ASM(f'({self.label_in_namespace})')
예제 #20
0
    def __init__(self,
                 input_vm=None,
                 compat=False,
                 annotate=False,
                 no_init=False,
                 ram_specs=None,
                 LCL=None,
                 ARG=None,
                 THIS=None,
                 THAT=None):
        self._input_vm = input_vm
        self._compat = compat
        self._annotate = annotate
        self._known_symbols = dict(VM2ASM.PREDEFINED_CONSTANTS)
        self._operations = None

        ASM.set_compat(self._compat)

        self.asm_output = []
        if annotate:
            self.asm_output.append(f'// SOURCE FILE={input_vm}')

        if not no_init:

            def set_ram(addr, value):
                asm = ASM(f'''
            // setup {addr}
            @{value}
            D=A
            @{addr}
            M=D
            ''')
                self.asm_output += asm.to_list(indent=4)

            self.asm_output.append('// INIT BEGIN')

            set_ram('SP', VM2ASM.STACK_BASE_ADDRESS)

            if not self._compat:
                asm = ASM('''
            // setup the W register as SP replacement
            @{VM2ASM.STACK_BASE_ADDRESS}
            W=A
            ''')
                self.asm_output += asm.to_list(indent=4)

            # if any of the runtime segment base address were given we set them. This is
            # needed to run the test programs supplied by the course
            if LCL:
                set_ram('LCL', LCL)

            if ARG:
                set_ram('ARG', ARG)

            if THIS:
                set_ram('THIS', THIS)

            if THAT:
                set_ram('THAT', THAT)

            if ram_specs and len(ram_specs):
                for spec in ram_specs:
                    addr, val = spec.split('=')
                    addr = int(addr)
                    val = int(val)
                    set_ram(addr, val)

            # set all temp variables to 0
            set_ram('T0', 0)
            set_ram('T1', 0)
            set_ram('T2', 0)

            if annotate:
                self.asm_output.append('// INIT END')
예제 #21
0
    def resolve(self, known_symbols=None):
        return ASM('''
      // save the return address at LCL-5 into FRAME b/c we will be updating LCL soon and also
      // if number of arguments is 0 ARG and LCL-5 are pointing to the same place and we will
      // end up overwriting the return address when we store the return value into ARG
      @5
      D=A
      @LCL
      A=M-D
      D=M
      @RET
      M=D

      // store the return value where ARG is pointing to, i.e. *ARG=*SP
      $load_sp
      A=A-1
      D=M
      @ARG
      A=M
      M=D

      // set A to 1 past ARG and save as SP
      @ARG
      A=M+1
      $save_sp

      // restore THAT at LCL-1
      @LCL
      A=M-1
      D=M
      @THAT
      M=D

      // restore THIS at LCL-2
      @2
      D=A
      @LCL
      A=M-D
      D=M
      @THIS
      M=D

      // restore ARG at LCL-3
      @3
      D=A
      @LCL
      A=M-D
      D=M
      @ARG
      M=D

      // restore LCL at LCL-4
      @4
      D=A
      @LCL
      A=M-D
      D=M
      @LCL
      M=D

      // load *RET into A and do an unconditional jump to that address
      @RET
      A=M
      0;JEQ
    ''')
예제 #22
0
파일: run.py 프로젝트: tmdavid/KU_Leuven
#for shape in shapes:
#    cshape,_=centerShape(shape)
#    cshapes.append(cshape)
#plotShapes(cshapes)
#ashape,_=alignAtoBProcrustes(cshapes[6],cshapes[1])
#plotShapes([cshapes[6],cshapes[1]])
#plotShapes([ashape,cshapes[1]])
#newshapes,meanShape,t=gpa(shapes)
#plotShapes([meanShape])
#plotShapes(newshapes)
#ashapemat=[]
#ashapemean=[]
for i in range(8):
    shapes=extractLandmarksForIncisorByIndex(landmarks,i)
    #newshapes,meanShape,t=gpa(shapes)
    #print 'Completed gpa of incisor ' + str(i) + ' in ' + str(t) + ' iterations '
    #plotShapes([meanShape])
    #ashapemat.append(newshapes)
    #ashapemean.append(meanShape)
    #X=prePCA(shapes)
    #l,W,mu=pcaV(X,0.9)
    #print W.shape
    #print l
    model = ASM(shapes,0.9)
    print model.getLambdas()
    modes=model.getModes()
    for j in range(len(model.getLambdas())):
        plotShapes(modes[j])   
    
    
예제 #23
0
    f = z[0] * sin(z[1])
    gradzf = ((sin(z[1]), z[0] * cos(z[1])))

    gradf = dot(gradzf, A)

    return f, gradf


# number of Monte Carlo samples to estimate Jacobian covariance
Nsamples = 1000
# input space dimension
m = 10

# construct dimension reduction object
asm = ASM(f, m, Nsamples)
W = asm.W
lamb = asm.lamb

# plot the eigenvalues
plt.semilogy(range(len(lamb)), lamb, '*')
plt.grid(True)
plt.xlabel('Index')
plt.ylabel('Eigenvalue')

# choose reduced dimension based on eigenvalue decay
n = 2
# number of design sites per reduced dimension
Nd = 6
# construct the kriging surface
kr = Kriging(asm, m, n, Nd)
예제 #24
0
    def resolve(self, known_symbols=None):
        """
    Note that we use the $_ macro to ensure a unique label b/c self.label_in_namespace is the same
    for calls to the same function in the same file
    """
        return ASM(f'''
      // push return addr onto the stack
      // load the return addr into D via A
      @$_{self.label_in_namespace}
      D=A
      $load_sp
      M=D
      $inc_sp

      // push LCL onto the stack
      // point M to LCL
      @LCL
      D=M
      $load_sp
      M=D
      $inc_sp

      // push ARG onto the stack
      @ARG
      D=M
      $load_sp
      M=D
      $inc_sp

      // push THIS onto the stack
      @THIS
      D=M
      $load_sp
      M=D
      $inc_sp

      // push THAT onto the stack
      @THAT
      D=M
      $load_sp
      M=D
      $inc_sp

      // recalculate ARG: ARG = SP - n - 5
      // note that to be backward compat  with HACK platform we can't manipulate the W
      // register directly

      // SP - n
      @{self.args[1]}
      D=A
      $load_sp
      // use D for destination b/c we are about to use A for a constant
      D=A-D

      // ... -5
      @5
      D=D-A

      // D now contains the new ARG value which we need to save into the ARG register
      @ARG
      M=D

      // write current SP into LCL register
      $load_sp
      D=A
      @LCL
      M=D

      // jump to the function entry point
      @{self.f_op.label_in_namespace}
      0;JEQ

      ($_{self.label_in_namespace})
  ''')