Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-4 of 4 total  RSS 

Scala builder pattern with abstract members

// This is an alternative implementation to the code I described here: http://blog.rafaelferreira.net/2008/07/type-safe-builder-pattern-in-scala.html
// It differs by (1) using abstract members and type members instead of parameters and type parameters and (2) contains visibility annotations.

object BuilderPattern {
  sealed abstract class Preparation
  case object Neat extends Preparation
  case object OnTheRocks extends Preparation
  case object WithWater extends Preparation

  sealed abstract class Glass
  case object Short extends Glass
  case object Tall extends Glass
  case object Tulip extends Glass

  case class OrderOfScotch private[BuilderPattern] (val brand:String, val mode:Preparation, val isDouble:Boolean, val glass:Option[Glass])

  abstract class TRUE  
  abstract class FALSE

  abstract class ScotchBuilder { self:ScotchBuilder =>
    protected[BuilderPattern] val theBrand:Option[String]
    protected[BuilderPattern] val theMode:Option[Preparation]
    protected[BuilderPattern] val theDoubleStatus:Option[Boolean]
    protected[BuilderPattern] val theGlass:Option[Glass]

    type HAS_BRAND
    type HAS_MODE
    type HAS_DOUBLE_STATUS

    def withBrand(b:String) = new ScotchBuilder {
      protected[BuilderPattern] val theBrand:Option[String] = Some(b)
      protected[BuilderPattern] val theMode:Option[Preparation] = self.theMode
      protected[BuilderPattern] val theDoubleStatus:Option[Boolean] = self.theDoubleStatus
      protected[BuilderPattern] val theGlass:Option[Glass] = self.theGlass

      type HAS_BRAND = TRUE
      type HAS_MODE = self.HAS_MODE
      type HAS_DOUBLE_STATUS = self.HAS_DOUBLE_STATUS
    }

    def withMode(p:Preparation) = new ScotchBuilder {
      protected[BuilderPattern] val theBrand:Option[String] = self.theBrand
      protected[BuilderPattern] val theMode:Option[Preparation] = Some(p)
      protected[BuilderPattern] val theDoubleStatus:Option[Boolean] = self.theDoubleStatus
      protected[BuilderPattern] val theGlass:Option[Glass] = self.theGlass

      type HAS_BRAND = self.HAS_BRAND
      type HAS_MODE = TRUE
      type HAS_DOUBLE_STATUS = self.HAS_DOUBLE_STATUS
    }


    def isDouble(b:Boolean) = new ScotchBuilder {
      protected[BuilderPattern] val theBrand:Option[String] = self.theBrand
      protected[BuilderPattern] val theMode:Option[Preparation] = self.theMode
      protected[BuilderPattern] val theDoubleStatus:Option[Boolean] = Some(b)
      protected[BuilderPattern] val theGlass:Option[Glass] = self.theGlass

      type HAS_BRAND = self.HAS_BRAND
      type HAS_MODE = self.HAS_MODE
      type HAS_DOUBLE_STATUS = TRUE
    }
     
    def withGlass(g:Glass) = new ScotchBuilder {
      protected[BuilderPattern] val theBrand:Option[String] = self.theBrand
      protected[BuilderPattern] val theMode:Option[Preparation] = self.theMode
      protected[BuilderPattern] val theDoubleStatus:Option[Boolean] = self.theDoubleStatus
      protected[BuilderPattern] val theGlass:Option[Glass] = Some(g)

      type HAS_BRAND = self.HAS_BRAND
      type HAS_MODE = self.HAS_MODE
      type HAS_DOUBLE_STATUS = self.HAS_DOUBLE_STATUS
    }

  }

  type CompleteBuilder = ScotchBuilder {
    type HAS_BRAND = TRUE
    type HAS_MODE = TRUE
    type HAS_DOUBLE_STATUS = TRUE
  }

  implicit def enableBuild(builder:CompleteBuilder) = new {
    def build() = 
      new OrderOfScotch(builder.theBrand.get, builder.theMode.get, builder.theDoubleStatus.get, builder.theGlass);
  }

  def builder = new ScotchBuilder {
    protected[BuilderPattern] val theBrand:Option[String] = None
    protected[BuilderPattern] val theMode:Option[Preparation] = None
    protected[BuilderPattern] val theDoubleStatus:Option[Boolean] = None
    protected[BuilderPattern] val theGlass:Option[Glass] = None

    type HAS_BRAND = FALSE
    type HAS_MODE = FALSE
    type HAS_DOUBLE_STATUS = FALSE
  }
}

scala extensions for emacs

// description of your code here

(require 'scala-mode)
(require 'compile)
(require 'flymake)
(require 'font-lock)

(defvar scala-build-commad nil)
(make-variable-buffer-local 'scala-build-command)

(add-hook 'scala-mode-hook
          (lambda ()
	    (flymake-mode-on)
	    ))

(defun flymake-scala-init ()
  (let* ((text-of-first-line (buffer-substring-no-properties (point-min) (min 20 (point-max)))))
    (progn
      (remove-hook 'after-save-hook 'flymake-after-save-hook t)
      (save-buffer)
      (add-hook 'after-save-hook 'flymake-after-save-hook nil t)
      (if (string-match "^//script" text-of-first-line)
	  (list "fsc" (list "-Xscript" "MainScript" "-d" "c:/tmp" buffer-file-name))
	(or scala-build-command (list "fsc" (list "-d" "c:/tmp" buffer-file-name))))
      )))

(push '(".+\\.scala$" flymake-scala-init) flymake-allowed-file-name-masks)
(push '("^\\(.*\\):\\([0-9]+\\): error: \\(.*\\)$" 1 2 nil 3) flymake-err-line-patterns)

(set (make-local-variable 'indent-line-function) 'scala-indent-line)

(defun scala-indent-line ()
  "Indent current line of Scala code."
  (interactive)
  (indent-line-to (max 0 (scala-calculate-indentation))))

(defun scala-calculate-indentation ()
  "Return the column to which the current line should be indented."
  (save-excursion
    (scala-maybe-skip-leading-close-delim)
    (let ((pos (point)))
      (beginning-of-line)
      (if (not (search-backward-regexp "[^\n\t\r ]" 1 0))
	  0
	(progn
	  (scala-maybe-skip-leading-close-delim)
	  (+ (current-indentation) (* 2 (scala-count-scope-depth (point) pos))))))))

(defun scala-maybe-skip-leading-close-delim ()
  (beginning-of-line)
  (forward-to-indentation 0)
  (if (looking-at "\\s)")
      (forward-char)
    (beginning-of-line)))

(defun scala-face-at-point (pos)
  "Return face descriptor for char at point."
  (plist-get (text-properties-at pos) 'face))

(defun scala-count-scope-depth (rstart rend)
  "Return difference between open and close scope delimeters."
  (save-excursion
    (goto-char rstart)
    (let ((open-count 0)
	  (close-count 0)
	  opoint)
      (while (and (< (point) rend)
		  (progn (setq opoint (point))
			 (re-search-forward "\\s)\\|\\s(" rend t)))
	(if (= opoint (point))
	    (forward-char 1)
	  (cond

            ;; Use font-lock-mode to ignore strings and comments
	   ((scala-face-at-point (- (point) 1))) 

	   ((looking-back "\\s)")
	    (incf close-count))
	   ((looking-back "\\s(")
	    (incf open-count))
	   )))
      (- open-count close-count))))


(provide 'scala-extensions)

Statically enforced range types in scala

Cute piece of code for statically checking array index accesses.

package ranges;

class Range(val start : Int, val end : Int){
  if (start >= end) throw new IndexOutOfBoundsException();

  def checkRange(min : Int, max : Int){
    if (min < start || max > end) throw new IndexOutOfBoundsException();
  }

  def inBounds(x : Int) : Index = unsafeFromInt(Math.min(end - 1, Math.max(x, start)));
  def checkBounds (x : Int) : Index = if (x < start || x >= end) throw new IndexOutOfBoundsException() else unsafeFromInt(x);

  private[Range] def unsafeFromInt (i : Int) = Index(i); // Separated into a method for refactoring and unsafe declaration.

  val range = start until end;
  val length = end - start;

  val maxIndex = unsafeFromInt(end - 1);
  val minIndex = unsafeFromInt(start);
  val indices = range.map(unsafeFromInt(_));

  trait Slice[T] extends Iterable[T] {
    def apply(i : Index) : T = unsafeApply(i);     
    def update(i : Index, t : T) = unsafeUpdate(i, t);

    private[Range] def unsafeApply(i : Int) : T;
    private[Range] def unsafeUpdate(i : Int, t : T) : Unit;

    def elements = range.elements.map(unsafeApply(_)); 
  } 

  class ArraySlice[T](array : Array[T]) extends Slice[T]{
    if (length < end) throw new IndexOutOfBoundsException();
    private[Range] def unsafeApply(i : Int) = array(i);
    private[Range] def unsafeUpdate(i : Int, t : T) : Unit = array(i) = t;

    override def foreach(f : T => Unit) = for (val i <- range) array(i);
  }

  class CheckedArray[T] extends Slice[T]{
    private val array = new Array[T](length);
    
    private[Range] def unsafeApply(i : Int) = array(i - start);
    private[Range] def unsafeUpdate(i : Int, t : T) : Unit = array(i - start) = t;
    
    override def foreach(f : T => Unit) = array.foreach(f);
  }

  implicit def toInteger(i : Index) = i.toInt;

  case class Index private[Range] (val toInt : Int){
    def max(y : Index) = unsafeFromInt(Math.max(this, y));
    def min(y : Index) = unsafeFromInt(Math.min(this, y));
    def mid(y : Index) = unsafeFromInt((this + y) >>> 1);
    def opposite = unsafeFromInt(end + start - 1 - this);
  }; 
}

Simple stack machine interpreter written in Scala

I wanted to implement a simple stack machine, and I wanted some practice with Scala. The two seemed to combine well.

I'll write up a description of the instruction set when I can be bothered, but it's hopefully pretty self explanatory.

package StackMachine;

import scala.collection.mutable._
import java.io.File;
import java.io.File._;
import java.io.BufferedReader;
import java.io.BufferedReader._ 
import java.io.InputStreamReader;
import java.io.InputStreamReader._;
import java.io.FileInputStream; 
import java.io.FileInputStream._;
import scala.collection.jcl.ArrayList;

class Memory(size : int) {
    private val internalMemory = new Array[int](size);
    
    override def toString : String = internalMemory.toString;    

    def load( location : int) = internalMemory(location % size);
    def store( location : int, value : int) { 
        internalMemory(location % size) = value; }
}

abstract class Instruction;

case class push (value : int) extends Instruction;
case class pop extends Instruction;
case class plus extends Instruction;
case class print extends Instruction;
case class break extends Instruction;
case class dup extends Instruction;
case class goto(instruction : int) extends Instruction;
case class noop extends Instruction;
case class ifCurrent(instruction : int) extends Instruction;
case class minus extends Instruction;
case class store(register : int) extends Instruction;
case class load(register : int) extends Instruction;
case class loadCurrent extends Instruction;
case class storeCurrent extends Instruction;
case class ifEmpty(instruction : int) extends Instruction;

object Instruction{
    def parse (value : String) = {
        if (value.startsWith("#")) noop()
        else {
        val split = splitString(value);
        val instruction = split._1.toLowerCase;
        val args = split._2;

        instruction match {
            case "pop"          => pop()
            case "plus"         => plus()
            case "print"        => print()
            case "push"         => push(args(0)) 
            case "break"        => break()
            case "dup"          => dup()
            case "goto"         => goto(args(0))
            case "ifstack"      => ifCurrent(args(0))
            case "store"        => store(args(0))
            case "load"         => load(args(0))
            case ""             => noop()
            case "minus"        => minus()
            case "ifempty"      => ifEmpty(args(0))
            case "loadcurrent"  => loadCurrent()
            case "storecurrent" => storeCurrent()
            case  _             => throw new Exception("Couldn't parse " + value)}}}

    private def splitString (value : String) = {
        val strings = value.split("\\s");
        
        Tuple2[String, List[int]](strings(0), 
            for {
                val i <- List.range(1, strings.length);
                strings(i) != ""}
            yield Integer.parseInt(strings(i)))
    }
}

class Machine(memorySize : int, states : Array[Instruction]) {
    val stack = new Stack[int]();
    val memory = new Memory(memorySize);
    var position = 0;
    
    private def advance { position = position + 1; }
    private def goto (instruction : int) { position = instruction - 1};    

    private def execute (instruction : Instruction) = 
        instruction match {
            // Stack manipulation
            case push(value)            => { stack += value; 
                                             advance; }
            case pop()                  => { stack.pop; 
                                             advance; }
            case dup()                  => { stack += stack.top; 
                                             advance; }
            
            // Arithmetic
            case plus()                 => { stack += (stack.pop + stack.pop); 
                                             advance; }
            
            case minus()                => { val second = stack.pop;
                                             val first = stack.pop;
                                             stack.push(if (second > first) 0 else (first - second));
                                             advance; }
            // Control flow
            // Our instructions are labelled from 1. Why? Laziness - vim does it that way.
            case goto(instruction)      => goto(instruction);
            case noop()                 => { advance; }
            
            case ifCurrent(instruction)   => { if (stack.pop == 0) goto(instruction); 
                                             else advance; }
            case ifEmpty(instruction)   => { if (stack.isEmpty) goto(instruction);
                                             else advance; }

            // Memory manipulation
            case load(register)         => { stack.push(memory.load(register));      
                                             advance; }                                   
            case store(register)        => { memory.store(register, stack.pop); 
                                             advance; }                                         
            case loadCurrent()          => { stack.push(memory.load(stack.pop)); 
                                             advance;}
            case storeCurrent()         => { val value = stack.pop;
                                             val register = stack.pop;
                                             memory.store(register, value);
                                             advance;}
            
            // IO instructions
            case print()                => { Console.println(stack.top); 
                                             advance; }
        };

    def run(){
        while (position < states.length){
            execute(states(position));
        }
    } 

    def execute (instructions : Iterable[Instruction]) : Unit = { 
        for (val instruction <- instructions)
        yield execute(instruction : Instruction);
        ();}
}

object Main{
    def main (args : Array[String]){
        if (args.length > 0){
            val file = new File(args(0));
            val reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));    

            var line = reader.readLine();
            
            val instructions = new ArrayList[Instruction]();

            while (line != null) {
                val instruction = Instruction.parse(line);
                instructions.add(instruction); 
                 
                
                line = reader.readLine();
                }

            val machine = new Machine(32, instructions.toArray);
            
            for (val i <- List.range(1, args.length))
            yield { machine.stack.push(Integer.parseInt(args(i))); }
            
            machine.run();
            
            Console.print("\n\n");
            Console.println("Machine terminated with:");
            Console.println("     Memory: " + machine.memory);
            Console.println("     Stack: " + machine.stack);
            Console.print("\n\n");
        }
        else Console.println("Please supply a file name");                
    }    
}

« Newer Snippets
Older Snippets »
Showing 1-4 of 4 total  RSS