(* models one-dimensional cellular automaton on a circle of finite radius arrays are faked as Strings, X's respresent live cells, dots represent dead cells, no error checking is done *) class CellularAutomaton inherits IO { population_map : String; init(map : String) : SELF_TYPE { { population_map <- map; self; } }; print() : SELF_TYPE { { out_string(population_map.concat("\n")); self; } }; num_cells() : Int { population_map.length() }; cell(position : Int) : String { population_map.substr(position, 1) }; cell_left_neighbor(position : Int) : String { if position = 0 then cell(num_cells() - 1) else cell(position - 1) fi }; cell_right_neighbor(position : Int) : String { if position = num_cells() - 1 then cell(0) else cell(position + 1) fi }; (* a cell will live if exactly 1 of itself and it's immediate neighbors are alive *) cell_at_next_evolution(position : Int) : String { if (if cell(position) = "X" then 1 else 0 fi + if cell_left_neighbor(position) = "X" then 1 else 0 fi + if cell_right_neighbor(position) = "X" then 1 else 0 fi = 1) then "X" else '.' fi }; evolve() : SELF_TYPE { (let position : Int in (let num : Int <- num_cells[] in (let temp : String in { while position < num loop { temp <- temp.concat(cell_at_next_evolution(position)); position <- position + 1; } pool; population_map <- temp; self; } ) ) ) }; }; class Main { cells : CellularAutomaton; main() : SELF_TYPE { { cells <- (new CellularAutomaton).init(" X "); cells.print(); (let countdown : Int <- 20 in while countdown > 0 loop { cells.evolve(); cells.print(); countdown <- countdown - 1; pool ); (* end let countdown self; } }; }; *) class AdditionalTest { -- Int test valid_int: Int <- 0123123; invalid_int: Int <- 0x1234; invalid_int2: Int <- 000_000; -- String test valid_str: String <- "hello world!\n"; escape_str: String <- "\"\n\\n\b\ff\t\K\*\00"; err_newline_str: String <- "This is not ok"; err_newline_str2: String <- "This is \ also not ok"; err_newline_str3: String <- "This is \ tricky lineno not ok"; ok_newline_string: String <- "This is \ ok"; -- Bool test valid_bool_true: Bool <- true = tRUE = trUe; valid_bool_false: Bool <- false = fALsE = fALSE; invalid_bool_true: Bool <- True = TRUe; invalid_bool_false: Bool <- False = FALSE; -- Invalid character test _hello: Bool <- 1 != 2 <> 3_3?; -- Comment test hello: Type <- 0; -- Valid nested comment (* (* feigling (* versagar scheisse scheisse*) verpfeif *) *) -- Invalid nested comment (* *) (( lost left close, Unmatched * ) expected *) (* (* lost right close, EOF in comment expected) *) };