package org.ojlang.runtime;

import lombok.Getter;
import lombok.experimental.Accessors;
import lombok.val;
import org.ojlang.models.DictionaryImpl;
import org.ojlang.models.MemoryImpl;
import org.ojlang.models.ParamStackImpl;
import org.ojlang.models.ReturnStackImpl;
import org.ojlang.models.contracts.Dictionary;
import org.ojlang.models.contracts.Memory;
import org.ojlang.models.contracts.ParamStack;
import org.ojlang.models.contracts.ReturnStack;

import java.io.Serializable;

/**
 * Oj runtime.
 *
 * @author Bahman Movaqar [Bahman AT BahmanM.com]
 */
@Accessors(fluent = true)
public class Runtime implements Serializable {

  final static private long serialVersionUID = 8428732629851491287L;

  @Getter
  final private Dictionary dict = new DictionaryImpl();

  @Getter
  final private Memory mem = new MemoryImpl();

  @Getter
  final private ReturnStack rs = new ReturnStackImpl();

  @Getter
  final private ParamStack ps = new ParamStackImpl();

  @Getter
  final private int sysMemSize = SystemWordsRegistry.size();

  private Runtime() {}

  /**
   * Creates a new instance of Oj runtime.
   * It basically initialises dictionary, return/param stacks with clean states,
   * and puts the XT of system words in memory (starting from 0).
   *
   * @see SystemWordsRegistry
   * @return
   */
  static public Runtime setup() {
    val runtime = new Runtime();
    SystemWordsRegistry.words().each(w -> {
      runtime.dict.put(w);
      runtime.mem.add(w.name());
    });
    return runtime;
  }

}

@@ -22,16 +22,39 @@
 ntime;%0A%0A
+import lombok.Builder;%0A
 import l
@@ -324,159 +324,100 @@
 cts.
-Dictionary;%0Aimport org.ojlang.models.contracts.Memory;%0Aimport org.ojlang.models.contracts.ParamStack;%0Aimport org.ojlang.models.contracts.ReturnStack
+*;%0A%0Aimport java.io.Serializable;%0Aimport java.util.Collection;%0Aimport java.util.Collections
 ;%0A
-%0A
 impo
@@ -424,31 +424,25 @@
 rt java.
-io.Serializable
+util.List
 ;%0A%0A/**%0A 
@@ -660,37 +660,60 @@
 L;%0A%0A  @Getter%0A  
-final
+private int xp;%0A%0A  @Getter%0A 
  private Diction
@@ -724,31 +724,8 @@
 dict
- = new DictionaryImpl()
 ;%0A%0A 
@@ -727,38 +727,32 @@
 t;%0A%0A  @Getter%0A  
-final 
 private Memory m
@@ -757,27 +757,8 @@
  mem
- = new MemoryImpl()
 ;%0A%0A 
@@ -760,38 +760,32 @@
 m;%0A%0A  @Getter%0A  
-final 
 private ReturnSt
@@ -794,32 +794,8 @@
 k rs
- = new ReturnStackImpl()
 ;%0A%0A 
@@ -797,38 +797,32 @@
 s;%0A%0A  @Getter%0A  
-final 
 private ParamSta
@@ -830,31 +830,8 @@
 k ps
- = new ParamStackImpl()
 ;%0A%0A 
@@ -841,22 +841,16 @@
 etter%0A  
-final 
 private 
@@ -867,39 +867,61 @@
 Size
- = SystemWordsRegistry.size();%0A
+;%0A%0A  /**%0A   * Private constructor.  Use %60init%60.%0A   */
 %0A  p
@@ -956,13 +956,17 @@
   * 
-Creat
+Initialis
 es a
@@ -1065,12 +1065,12 @@
 ith 
-clea
+give
 n st
@@ -1186,121 +1186,509 @@
  * @
-return%0A   */%0A  static public Runtime setup() %7B%0A    val runtime = new Runtime();%0A    SystemWordsRegistry.words().e
+param systat system execution state%0A   * @param sysWords system words%0A   * @return a new instance of runtime%0A   */%0A  static public Runtime init(%0A    SystemState systat,%0A    List%3CSystemWord%3E sysWords%0A  ) %7B%0A    assert(systat != null && sysWords != null);%0A    val runtime = new Runtime();%0A    runtime.mem = systat.mem();%0A    runtime.dict = systat.dict();%0A    runtime.rs = systat.rs();%0A    runtime.ps = systat.ps();%0A    runtime.xp = systat.xp();%0A    runtime.sysMemSize = sysWords.size();%0A    sysWords.forE
 ach(

add sysWords to init params