Skip to content

Instantly share code, notes, and snippets.

@seanjensengrey
Forked from pachacamac/mrisc.rb
Created September 17, 2011 18:08
Show Gist options
  • Select an option

  • Save seanjensengrey/1224188 to your computer and use it in GitHub Desktop.

Select an option

Save seanjensengrey/1224188 to your computer and use it in GitHub Desktop.

Revisions

  1. Pacha Camac revised this gist Jul 10, 2011. 1 changed file with 22 additions and 0 deletions.
    22 changes: 22 additions & 0 deletions mrisc.rb
    Original file line number Diff line number Diff line change
    @@ -58,3 +58,25 @@ def numeric?(n); true if Float(n) rescue false; end
    jig,b,1,@power1;
    jmp,@rj; *return from subroutine*
    ')

    MRISC.new.run('
    *==========[ stack test ]===========*
    *construct for a subroutine call*
    let,n,7;
    let,@rj,_pc;
    add,@rj,2;
    jmp,@fac;
    out,n; *print result*
    end; *end here*
    *=========[ subroutines ]=========*
    @fac; *calculates faculty of n, uses t, uses the stack, result in n*
    pus,n;
    sub,n,1;
    jig,n,1,@fac;
    @facloop;
    pop,t;
    mul,n,t;
    jig,_ss,0,@facloop;
    jmp,@rj;
    *===================================*
    ')
  2. Pacha Camac created this gist Jul 7, 2011.
    60 changes: 60 additions & 0 deletions mrisc.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,60 @@
    #!/usr/bin/env ruby

    class MRISC
    def run(code)
    tokens = code.gsub(/(\*.*?\*)|[^a-z0-9,-;@\._]/,'').split(';')
    @vars,stack,i = {:_pc=>-1,:_oc=>0},[],0
    tokens.map!{|t| t.chars.first=='@' ? (@vars[t.to_sym]=i-1;nil) : (i+=1;t.split(',').map{|e|numeric?(e) ? e.to_i : e.to_sym})}.compact!
    while @vars[:_pc] < tokens.size-1
    @vars[:_pc] += 1
    @vars[:_oc] += 1
    @vars[:_ss] = stack.size
    raise 'too many operations!' if @vars[:_oc] > 9999
    cmd,a,b,c = tokens[@vars[:_pc]]
    case cmd
    when :let; set(a,b)
    when :out; puts get(a)
    when :dbg; puts a
    when :add; set(a,get(a)+get(b))
    when :sub; set(a,get(a)-get(b))
    when :mul; set(a,get(a)*get(b))
    when :mod; set(a,get(a)%get(b))
    when :div; set(a,get(a)/get(b))
    when :jmp; @vars[:_pc]=get(a)
    when :jis; @vars[:_pc]=get(c) if get(a)<get(b)
    when :jig; @vars[:_pc]=get(c) if get(a)>get(b)
    when :jie; @vars[:_pc]=get(c) if get(a)==get(b)
    when :jiu; @vars[:_pc]=get(c) if get(a)!=get(b)
    when :end; @vars[:_pc]=tokens.size
    when :pus; stack.push(get(a))
    when :pop; set(a,stack.pop)
    else raise "unknown command '#{cmd}' at #{tokens[@vars[:_pc]].join(',')}"
    end
    end
    @vars
    end

    private
    def get(s); (@vars.key?(s) ? @vars[s] : numeric?(s) ? s : 0).to_i; end
    def set(s,v); @vars[s] = get(v); end
    def numeric?(n); true if Float(n) rescue false; end
    end

    MRISC.new.run('
    *=== Main ===*
    let,a,3; *arg 1 and result*
    let,b,5; *arg 2*
    let,@rj,_pc; *return address*
    add,@rj,2;
    jmp,@power; *subroutine call*
    out,a; *print result*
    end;
    *=== Subroutines ===*
    @power; *calculates pow(a,b) result in a. uses tmp*
    let,tmp,a;
    @power1;
    mul,a,tmp;
    sub,b,1;
    jig,b,1,@power1;
    jmp,@rj; *return from subroutine*
    ')