This commit is contained in:
QkoSad
2025-07-16 13:00:37 +03:00
commit 7894b48931
806 changed files with 162532 additions and 0 deletions
+132
View File
@@ -0,0 +1,132 @@
class Main{
static Array mem;
/** Initializes the screen, and locates the cursor at the screen's top-left. */
function void test_init() {
let mem = 0;
return;
}
function void main(){
var String s;
var int i;
let s = String.new(10);
do Main.test_init();
let s = Main.readLine("String: ");
let i = Main.readInt("INT: ");
do Output.printString(s);
do Output.printInt(i);
return;
}
function char keyPressed(){
return mem[24576];
}
function int readInt_stolen(String message){
var starting a;
var int b;
let a = Main.readLine_stolen(message);
let b = String.intValue(a);
do String.dispose(a);
return b;
}
function string readLine_stolen(String message){
var char a, b ,c;
var String d;
var bool e;
let d = String.new(80);
do Output.printString(message);
let b = String.newLine();
let c = String.backSpace();
while (~e){
let a = Main.readChar();
let e = a = b;
if (~e){
if (a = c){
do d.eraseLastChar();
}
else{
do d.appendChar(a);
}
}
}
return d;
}
/**
* Displays the message on the screen, reads from the keyboard the entered
* text until a newline character is detected, echoes the text to the screen,
* and returns its value. Also handles user backspaces.
*/
function String readLine(String message){
var String s, b;
var char c;
let s = String.new(100);
do Output.printString(message);
while (true){
let c = Main.readChar();
if (c = 128){
return s;
}
else{
if (c = 129){
do s.eraseLastChar();
}
else{
do s.appendChar(c);
}
}
}
}
/**
* Waits until a key is pressed on the keyboard and released,
* then echoes the key to the screen, and returns the character
* of the pressed key.
*/
function char readChar(){
var char a, b;
do Output.printChar(0);
while ((b = 0) | (a > 0)){
let a = Main.keyPressed();
if (a > 0){
let b = a;
}
}
do Output.printChar(String.backSpace());
do Output.printChar(b);
return b;
}
/**
* Displays the message on the screen, reads from the keyboard the entered
* text until a newline character is detected, echoes the text to the screen,
* and returns its integer value (until the first non-digit character in the
* entered text is detected). Also handles user backspaces.
*/
function int readInt(String message) {
var String s;
var char c;
let s = String.new(100);
do Output.printString(message);
while (true){
let c = Main.readChar(c);
if (c = 128){
return s.intValue();
}
else{
if (c = 129){
let s = s.eraseLastChar();
}
else{
if ((c > 47) & (c < 57)){
let s = s.appendChar(c);
}
}
}
}
}
}
+341
View File
@@ -0,0 +1,341 @@
class Main {
static int division_tmp;
static Array mem;
static Array st;
static int f;
static boolean color;
/** Initializes the library. */
function void init_test() {
var int a;
let st = Array.new(16);
let st[0] = 1;
while (a < 15){
let a = a + 1;
let st[a] = st[a - 1] + st[a - 1];
}
let color = 1;
return;
}
function void main(){
do Main.init_test();
do Main.test_drawPixel(256,128);
do Main.test_drawPixel(255,128);
do Main.test_drawPixel(257,128);
do Main.test_changeColor(0);
do Main.test_drawPixel(256,128);
return;
}
function void test_changeColor(boolean x){
let color = x;
return;
}
function void test_clearScreen(){
var int a;
let a = 16384;
while (a < 24575){
let mem[a] = 0;
let a = a + 1;
}
return;
}
function void test_drawRectangle(int x1, int y1, int x2, int y2){
var int a, tmp;
if (x1 > x2){
let tmp = x1;
let x1 = x2;
let x2 = tmp;
}
if (y1 > y2){
let tmp = y1;
let y1 = y2;
let y2 = tmp;
}
if((x1 < 0) | (x2 > 511) | (y1 < 0) | (y2 > 255)){
do Sys.error(8);
}
while(a < y2){
do Screen.drawLine(x1, y1 + a, x2, y1 + a);
let a = a + 1;
}
return;
}
function void test_drawCicle(int x, int y, int r){
var int dy, dx, tmp;
if(r > 181){
do Sys.error(7);
}
let dy = - r;
while (dy < r){
let tmp = Math.sqrt((r * r) - (dy * dy));
do Screen.drawLine(x - tmp, y + dy, x + tmp, y + dy);
let dy = dy + 1;
}
return;
}
function void test_drawLine_optimize(int x1, int y1, int x2, int y2){
var int diff, dx, dy, a, b, tmp;
if (x1 > x2){
let tmp = x1;
let x1 = x2;
let x2 = tmp;
}
if (y1 > y2){
let tmp = y1;
let y1 = y2;
let y2 = tmp;
}
if((x1 < 0) | (x2 > 511) | (y1 < 0) | (y2 > 255)){
do Sys.error(8);
}
let dx = x2 - x1;
let dy = y2 - y1;
if (dx = 0){
while(~(b > dy)){
do Screen.drawPixel(x1, y1 + b);
let b = b + 1;
}
return;
}
if (dy = 0){
while(~(a > dx)){
do Screen.drawPixel(x1 + a, y1);
let a = a + 1;
}
return;
}
while ((~(a > dx)) & (~(b > dy))){
do Screen.drawPixel(x1 + a, y1 + b);
if (diff < 0){
let a = a + 1;
let diff = diff + dy;
}
else{
let b = b + 1;
let diff = diff - dx;
}
}
return;
}
function void test_drawPixel(int x, int y) {
var int value, address, bit, mem_block;
if ((x > 511) | (x < 0) | (y > 255) | (y < 0)){
do Sys.error(7);
}
let mem_block = x / 16;
let address = (32 * y) + mem_block + 16384;
let value = mem[address];
let bit = x - (mem_block * 16);
if (color = 1){
let mem[address] = st[bit] | value;
}
else{
let mem[address] = (~st[bit])& value;
}
return;
}
function int test_multiply(int x, int y){
var int sum, temp, y_comp, i, neg;
let neg = ((x < 0) & (y > 0)) | ((x > 0) & (y < 0));
let x = Math.abs(x);
let y = Math.abs(y);
if (x < y){
let temp = x;
let x = y;
let y = temp;
}
if (y = 1){
if(neg){
return -x;
}
return x;
}
while((y_comp - 1) < (y - 1)){
if ((st[i] & y) > 0) {
let sum = sum + x;
let y_comp = y_comp + st[i];
}
let x = x + x;
let i = i + 1;
}
if(neg){
let sum = -sum;
}
return sum;
}
function int test_max(int x, int y){
if (x > y){
return x;
}
return y;
}
function int test_min(int x, int y){
if (x < y){
return x;
}
return y;
}
function int test_sqrt(int x) {
var int j, b, d, y;
if (x < 0){
do Sys.error(4);
}
let j = 7;
while (j > -1){
let d = y + st[j];
let b = Main.test_multiply(d,d);
if ((~(b > x)) & (b > 0)){
let y = d;
}
let j = j - 1;
}
return y;
}
function int test_divide(int x, int y) {
var int q, neg;
if (f = 0){
let division_tmp = 0;
let neg = ((x < 0) & (y > 0)) | ((x > 0) & (y < 0));
let x = Math.abs(x);
let y = Math.abs(y);
if (y = 0){
do Sys.error(3);
}
let f = 1;
}
if ((y > x) | (y < 0)){
return 0;
}
let q = test_divide(x, y + y);
let f = 0;
let q = Math.abs(q);
if ((q & 1) = 1){
let division_tmp = division_tmp + y + y;
}
if (x - division_tmp < y){
if (neg){
return -(q + q);
}
return q + q;
}
else{
if (neg){
return -(q + q + 1);
}
return q + q + 1;
}
}
function int test_abs(int x) {
if (x > 0){
return x;
}
return -x;
}
function int test_peek(int x){
return mem[x];
}
function void test_poke(int x, int y){
let mem[x] = y;
return;
}
function int test_dealloc_stolen(Array x){
var int obj_add,b;
let obj_add = x - 2;
let b = obj_add[1];
if (b[0] = 0){
let obj_add[0] = obj_add[1] - obj_add -2;
}
else{
let obj_add[0] = obj_add[1] - obj_add + b[0];
if (b[1] = b +2){
let obj_add[1] = obj_add + 2;
}
else{
let obj_add[1] = b[1];
}
}
}
function void test_dealloc(Array o){
var Array current_block;
let current_block = 2048;
let o[1]= current_block[1];
let current_block[1] = o;
}
function int test_alloc(int size){
var Array current_block;
var int tmp;
let current_block = 2048;
if (size < 0){
do Sys.error(5);
}
if (size = 0){
let size = 1;
}
while (current_block[0] < (size + 2)) {
let current_block = current_block[1];
}
let current_block[0] = current_block[0] - size - 2;
let current_block = current_block + current_block[0] + 2;
let current_block[0] = size;
return current_block + 2;
}
function int test_alloc_stolen(int x){
var Array curret_block, next_block;
if (x < 0){
do Sys.error(5);
}
if (x = 0){
let x = 1;
}
let curret_block = 2048;
let curret_block[0] = 14334;
let curret_block[1] = 2050;
while ((curret_block < 16383) & (curret_block[0] < x)){
let next_block = curret_block[1];
if ((curret_block[0] = 0) | (next_block > 16382) | (next_block[0] = 0)){ // this sends directly out of while
let curret_block = next_block;
}
else {
let curret_block[0] = curret_block[1] - curret_block + next_block[0]; // cb size =
if (next_block[1] = next_block + 2){
let curret_block[1] = curret_block + 2;
}
else{
let curret_block[1] = next_block[1];
}
}
}
if ((curret_block + x) > 16379){
do Sys.error(6);
}
if (curret_block[0] > (x + 2)){ // if current block fills the desired size perfectly
let curret_block[x + 2] = curret_block[0] - x -2;
if (curret_block[1] = curret_block + 2){
let curret_block[x + 3] = curret_block + x + 4;
}
else{
let curret_block[x + 3] = curret_block[1];
}
}
let curret_block[0] = 0;
return (curret_block + 2);
}
}
+280
View File
@@ -0,0 +1,280 @@
class Main {
static Array charMaps;
static int address;
static bool half;
/** Initializes the screen, and locates the cursor at the screen's top-left. */
function void test_init() {
do Main.initMap();
do Main.moveCursor(0, 0);
return;
}
function void main(){tInt(i);
return;
}
// Returns the character map (array of size 11) of the given character.
// If the given character is invalid or non-printable, returns the
// character map of a black square.
function Array getMap(char c) {
if ((c < 32) | (c > 126)) {
let c = 0;
}
return charMaps[c];
}
/** Moves the cursor to the j-th column of the i-th row,
* and erases the character displayed there. */
function void moveCursor(int i, int j) {
var int count, display;
var Array r, char;
if (j = 0){
let half = true;
}
else{
let half = (j / 2) * 2 = j; // chetno true, 1vaa chast
}
let address = (352 * i) + (j / 2) + 16384;
let char = Main.getMap(32);
while (count < 11){
if (half){
let display = r[address] & (-256);
let r[address] = char[count] | display;
}
else{
let display = r[address] & 255;
let r[address] = (char[count]*256) | display;
}
let count = count + 1;
let address = address + 32;
}
let address = address - 352;
return;
}
/** Displays the given character at the cursor location,
* and advances the cursor one column forward. */
function void printChar(char c) {
var Array char, r;
var int count, display;
let char = Main.getMap(c);
while (count < 11){
if (half){
let display = r[address] & (-256);
let r[address] = char[count] | display;
}
else{
let display = r[address] & 255;
let r[address] = (char[count]*256) | display;
}
let count = count + 1;
let address = address + 32;
}
if (half){
let address = address - 352;
let half = false;
}
else{
if (address > 24480){
let address = 16384;
let half = true;
}
else{
let address = address - 351;
let half = true;
}
}
return;
}
/** displays the given string starting at the cursor location,
* and advances the cursor appropriately. */
function void printString(String s) {
var int i, length;
let length = s.length();
while (i < length){
do Main.printChar(s[i+2]);
let i = i + 1;
}
return;
}
/** Displays the given integer starting at the cursor location,
* and advances the cursor appropriately. */
function void printInt(int i) {
var String s;
let s = String.new(6);
do s.setInt(i);
do Main.printString(s);
return;
}
/** Advances the cursor to the beginning of the next line. */
function void println() {
var int row;
let row = (((address - 16384) / 32)/11) + 1;
if (row > 32){
let row = 0;
}
do Main.moveCursor(row, 0);
return;
}
/** Moves the cursor one column back. */
function void backSpace() {
if (address = 16384){
let address = 24191;
let half = true;
return;
}
if (half){
let address = address - 1;
let half = false;
}
else{
let half = true;
}
return;
}
// Initializes the character map array
function void initMap() {
var int i;
let charMaps = Array.new(127);
// Black square, used for displaying non-printable characters.
do Main.create(0,63,63,63,63,63,63,63,63,63,0,0);
// Assigns the bitmap for each character in the charachter set.
// The first parameter is the character index, the next 11 numbers
// are the values of each row in the frame that represents this character.
do Main.create(32,0,0,0,0,0,0,0,0,0,0,0); //
do Main.create(33,12,30,30,30,12,12,0,12,12,0,0); // !
do Main.create(34,54,54,20,0,0,0,0,0,0,0,0); // "
do Main.create(35,0,18,18,63,18,18,63,18,18,0,0); // #
do Main.create(36,12,30,51,3,30,48,51,30,12,12,0); // $
do Main.create(37,0,0,35,51,24,12,6,51,49,0,0); // %
do Main.create(38,12,30,30,12,54,27,27,27,54,0,0); // &
do Main.create(39,12,12,6,0,0,0,0,0,0,0,0); // '
do Main.create(40,24,12,6,6,6,6,6,12,24,0,0); // (
do Main.create(41,6,12,24,24,24,24,24,12,6,0,0); // )
do Main.create(42,0,0,0,51,30,63,30,51,0,0,0); // *
do Main.create(43,0,0,0,12,12,63,12,12,0,0,0); // +
do Main.create(44,0,0,0,0,0,0,0,12,12,6,0); // ,
do Main.create(45,0,0,0,0,0,63,0,0,0,0,0); // -
do Main.create(46,0,0,0,0,0,0,0,12,12,0,0); // .
do Main.create(47,0,0,32,48,24,12,6,3,1,0,0); // /
do Main.create(48,12,30,51,51,51,51,51,30,12,0,0); // 0
do Main.create(49,12,14,15,12,12,12,12,12,63,0,0); // 1
do Main.create(50,30,51,48,24,12,6,3,51,63,0,0); // 2
do Main.create(51,30,51,48,48,28,48,48,51,30,0,0); // 3
do Main.create(52,16,24,28,26,25,63,24,24,60,0,0); // 4
do Main.create(53,63,3,3,31,48,48,48,51,30,0,0); // 5
do Main.create(54,28,6,3,3,31,51,51,51,30,0,0); // 6
do Main.create(55,63,49,48,48,24,12,12,12,12,0,0); // 7
do Main.create(56,30,51,51,51,30,51,51,51,30,0,0); // 8
do Main.create(57,30,51,51,51,62,48,48,24,14,0,0); // 9
do Main.create(58,0,0,12,12,0,0,12,12,0,0,0); // :
do Main.create(59,0,0,12,12,0,0,12,12,6,0,0); // ;
do Main.create(60,0,0,24,12,6,3,6,12,24,0,0); // <
do Main.create(61,0,0,0,63,0,0,63,0,0,0,0); // =
do Main.create(62,0,0,3,6,12,24,12,6,3,0,0); // >
do Main.create(64,30,51,51,59,59,59,27,3,30,0,0); // @
do Main.create(63,30,51,51,24,12,12,0,12,12,0,0); // ?
do Main.create(65,12,30,51,51,63,51,51,51,51,0,0); // A
do Main.create(66,31,51,51,51,31,51,51,51,31,0,0); // B
do Main.create(67,28,54,35,3,3,3,35,54,28,0,0); // C
do Main.create(68,15,27,51,51,51,51,51,27,15,0,0); // D
do Main.create(69,63,51,35,11,15,11,35,51,63,0,0); // E
do Main.create(70,63,51,35,11,15,11,3,3,3,0,0); // F
do Main.create(71,28,54,35,3,59,51,51,54,44,0,0); // G
do Main.create(72,51,51,51,51,63,51,51,51,51,0,0); // H
do Main.create(73,30,12,12,12,12,12,12,12,30,0,0); // I
do Main.create(74,60,24,24,24,24,24,27,27,14,0,0); // J
do Main.create(75,51,51,51,27,15,27,51,51,51,0,0); // K
do Main.create(76,3,3,3,3,3,3,35,51,63,0,0); // L
do Main.create(77,33,51,63,63,51,51,51,51,51,0,0); // M
do Main.create(78,51,51,55,55,63,59,59,51,51,0,0); // N
do Main.create(79,30,51,51,51,51,51,51,51,30,0,0); // O
do Main.create(80,31,51,51,51,31,3,3,3,3,0,0); // P
do Main.create(81,30,51,51,51,51,51,63,59,30,48,0);// Q
do Main.create(82,31,51,51,51,31,27,51,51,51,0,0); // R
do Main.create(83,30,51,51,6,28,48,51,51,30,0,0); // S
do Main.create(84,63,63,45,12,12,12,12,12,30,0,0); // T
do Main.create(85,51,51,51,51,51,51,51,51,30,0,0); // U
do Main.create(86,51,51,51,51,51,30,30,12,12,0,0); // V
do Main.create(87,51,51,51,51,51,63,63,63,18,0,0); // W
do Main.create(88,51,51,30,30,12,30,30,51,51,0,0); // X
do Main.create(89,51,51,51,51,30,12,12,12,30,0,0); // Y
do Main.create(90,63,51,49,24,12,6,35,51,63,0,0); // Z
do Main.create(91,30,6,6,6,6,6,6,6,30,0,0); // [
do Main.create(92,0,0,1,3,6,12,24,48,32,0,0); // \
do Main.create(93,30,24,24,24,24,24,24,24,30,0,0); // ]
do Main.create(94,8,28,54,0,0,0,0,0,0,0,0); // ^
do Main.create(95,0,0,0,0,0,0,0,0,0,63,0); // _
do Main.create(96,6,12,24,0,0,0,0,0,0,0,0); // `
do Main.create(97,0,0,0,14,24,30,27,27,54,0,0); // a
do Main.create(98,3,3,3,15,27,51,51,51,30,0,0); // b
do Main.create(99,0,0,0,30,51,3,3,51,30,0,0); // c
do Main.create(100,48,48,48,60,54,51,51,51,30,0,0); // d
do Main.create(101,0,0,0,30,51,63,3,51,30,0,0); // e
do Main.create(102,28,54,38,6,15,6,6,6,15,0,0); // f
do Main.create(103,0,0,30,51,51,51,62,48,51,30,0); // g
do Main.create(104,3,3,3,27,55,51,51,51,51,0,0); // h
do Main.create(105,12,12,0,14,12,12,12,12,30,0,0); // i
do Main.create(106,48,48,0,56,48,48,48,48,51,30,0); // j
do Main.create(107,3,3,3,51,27,15,15,27,51,0,0); // k
do Main.create(108,14,12,12,12,12,12,12,12,30,0,0); // l
do Main.create(109,0,0,0,29,63,43,43,43,43,0,0); // m
do Main.create(110,0,0,0,29,51,51,51,51,51,0,0); // n
do Main.create(111,0,0,0,30,51,51,51,51,30,0,0); // o
do Main.create(112,0,0,0,30,51,51,51,31,3,3,0); // p
do Main.create(113,0,0,0,30,51,51,51,62,48,48,0); // q
do Main.create(114,0,0,0,29,55,51,3,3,7,0,0); // r
do Main.create(115,0,0,0,30,51,6,24,51,30,0,0); // s
do Main.create(116,4,6,6,15,6,6,6,54,28,0,0); // t
do Main.create(117,0,0,0,27,27,27,27,27,54,0,0); // u
do Main.create(118,0,0,0,51,51,51,51,30,12,0,0); // v
do Main.create(119,0,0,0,51,51,51,63,63,18,0,0); // w
do Main.create(120,0,0,0,51,30,12,12,30,51,0,0); // x
do Main.create(121,0,0,0,51,51,51,62,48,24,15,0); // y
do Main.create(122,0,0,0,63,27,12,6,51,63,0,0); // z
do Main.create(123,56,12,12,12,7,12,12,12,56,0,0); // {
do Main.create(124,12,12,12,12,12,12,12,12,12,0,0); // |
do Main.create(125,7,12,12,12,56,12,12,12,7,0,0); // }
do Main.create(126,38,45,25,0,0,0,0,0,0,0,0); // ~
return;
}
// Creates the character map array of the given character index, using the given values.
function void create(int index, int a, int b, int c, int d, int e,
int f, int g, int h, int i, int j, int k) {
var Array map;
let map = Array.new(11);
let charMaps[index] = map;
let map[0] = a;
let map[1] = b;
let map[2] = c;
let map[3] = d;
let map[4] = e;
let map[5] = f;
let map[6] = g;
let map[7] = h;
let map[8] = i;
let map[9] = j;
let map[10] = k;
return;
}
}
+148
View File
@@ -0,0 +1,148 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/12/String.jack
/**
* Represents character strings. In addition for constructing and disposing
* strings, the class features methods for getting and setting individual
* characters of the string, for erasing the string's last character,
* for appending a character to the string's end, and more typical
* string-oriented operations.
*/
class String {
field Array str;
field int length;
static bool neg;
/** constructs a new empty string with a maximum length of maxLength
* and initial length of 0. */
constructor String new(int maxLength) {
if (maxLength > 0){
let str = Array.new(maxLength);
}
let length = 0;
return this;
}
/** Disposes this string. */
method void dispose() {
if(length > 0){
do str.dispose();
}
do Memory.deAlloc(this);
return;
}
/** Returns the current length of this string. */
method int length() {
return length;
}
/** Returns the character at the j-th location of this string. */
method char charAt(int j) {
if(j > length){
do Sys.error(7);
}
return str[j];
}
/** Sets the character at the j-th location of this string to c. */
method void setCharAt(int j, char c) {
if(j > length){
do Sys.error(7);
}
let str[j] = c;
return;
}
/** Appends c to this string's end and returns this string. */
method String appendChar(char c) {
let str[length] = c;
let length = length + 1;
return this;
}
/** Erases the last character from this string. */
method void eraseLastChar() {
let str[length] = 0;
let length = length - 1;
return;
}
/** Returns the integer value of this string,
* until a non-digit character is detected. */
method int intValue() {
var int d, sum, i;
var bool f;
while(i < length){
let d = str[i]; // kak da go zavyrtq v realen int
if ((d > 47) & (d < 58)){
let sum = (sum * 10) + (d - 48);
}
else{
if((i = 0) & (d = 45)){
let f = true;
}
else{
let i = length;
}
}
let i = i + 1;
}
if (f){
return -sum;
}
return sum;
}
/** Sets this string to hold a representation of the given value. */
method void setInt(int val) {
var int lastDigit, a,i;
var char c;
if(val < 0){
let neg = true;
let val = -val;
}
let a = val / 10;
let lastDigit = val - (a * 10);
let i = 48;
while (i < 58){
if (i = (48 + lastDigit)){
let c = i;
let i = 59;
}
let i = i + 1;
}
if (val < 10){
let length = 0;
if (neg){
let neg = false;
do this.appendChar(45);
}
do this.appendChar(c);
return;
}
else{
do this.setInt(a);
do this.appendChar(c);
}
return;
}
/** Returns the new line character. */
function char newLine() {
return 128;
}
/** Returns the backspace character. */
function char backSpace() {
return 129;
}
/** Returns the double quote (") character. */
function char doubleQuote() {
return 34;
}
}