├── README.md └── src ├── computer.css ├── logic_gates.html ├── full_adder.html ├── 4bit.html └── gen.js /README.md: -------------------------------------------------------------------------------- 1 | # CSS Computer 2 | 3 | - logic gates: http://shuding.github.io/css-computer/src/logic_gates.html 4 | - full adder: http://shuding.github.io/css-computer/src/full_adder.html 5 | - 4bit addition: http://shuding.github.io/css-computer/src/4bit.html 6 | - flip-flop...? 7 | 8 | ## About 9 | 2015, Shu Ding , MIT licensed. 10 | -------------------------------------------------------------------------------- /src/computer.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 15px; 3 | font-family: 'Consolas', monospace; 4 | } 5 | 6 | input.cc-switch[type=checkbox] { 7 | border: none; 8 | background: none; 9 | -webkit-appearance: none; 10 | -moz-appearance: none; 11 | appearance: none; 12 | outline: none; 13 | font-weight: bold; 14 | cursor: pointer; 15 | color: blue; 16 | } 17 | input.cc-switch[type=checkbox]:not(:checked):before { 18 | content: "0"; 19 | font-size: 10px; 20 | line-height: 10px; 21 | font-style: normal; 22 | } 23 | input.cc-switch[type=checkbox]:checked:before { 24 | content: "1"; 25 | font-size: 10px; 26 | line-height: 10px; 27 | font-style: normal; 28 | } 29 | 30 | .cc-container { 31 | position: relative; 32 | display: inline-block; 33 | width: 10px; 34 | height: 10px; 35 | font-size: 0; 36 | vertical-align: middle; 37 | overflow: hidden; 38 | } 39 | .cc-container:after { 40 | content: "0"; 41 | position: absolute; 42 | height: 10px; 43 | font-size: 10px; 44 | line-height: 14px; 45 | font-style: normal; 46 | } 47 | .cc, .cc-and, .cc-or { 48 | position: relative; 49 | display: inline-block; 50 | max-width: 10px; 51 | height: 10px; 52 | overflow: hidden; 53 | } 54 | .cc:after { 55 | content: "1"; 56 | position: absolute; 57 | height: 10px; 58 | font-size: 10px; 59 | line-height: 14px; 60 | font-style: normal; 61 | } 62 | .cc-and > *:first-child { 63 | margin-left: -10px; 64 | } 65 | -------------------------------------------------------------------------------- /src/logic_gates.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Logic Gates 6 | 7 | 8 | 9 | 23 | 24 | A = 25 | 26 |
27 | 28 | B = 29 | 30 |
31 | 32 | A&B = 33 |
34 | 35 | 36 | 37 | 38 |
39 | 40 |
41 | 42 | A|B = 43 |
44 | 45 | 46 | 47 | 48 |
49 | 50 |
51 | 52 | ~A = 53 |
54 | 55 |
56 | 57 |
58 | 59 | ~B = 60 |
61 | 62 |
63 | 64 |
65 | 66 | A^B = (A|B)&(~A|~B) = 67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/full_adder.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Full Adder 6 | 7 | 8 | 9 | 27 | 28 | A = 29 | 30 |
31 | 32 | B = 33 | 34 |
35 | 36 | S = 37 | 38 |
39 | 40 | A+B+S = A^B^S = 41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
69 | 70 |
71 | 72 | carry = 73 |
74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /src/4bit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CSS Computer 6 | 7 | 8 | 9 | 10 | 18 | 19 | a = 21 | 22 |
23 | 24 | b = 26 | 27 |
28 | 29 | a + b = 30 |
31 | 44 |
45 |
46 | 55 |
56 |
57 | 62 |
63 |
64 | 66 |
67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/gen.js: -------------------------------------------------------------------------------- 1 | (function (window, undefined) { 2 | 3 | function Variable() { 4 | this.name = ''; 5 | } 6 | 7 | Variable.prototype.set = function (name) { 8 | this.name = name; 9 | }; 10 | 11 | Variable.prototype.output = function (bit) { 12 | return ''; 13 | }; 14 | 15 | function Expression() { 16 | this.type = ''; 17 | this.left = null; 18 | this.right = null; 19 | } 20 | 21 | Expression.prototype.parse = function (str, l, r) { 22 | while (l < r && str[l] == ' ') { 23 | ++l; 24 | } 25 | while (l < r && str[r - 1] == ' ') { 26 | --r; 27 | } 28 | 29 | if (l >= r) { 30 | return null; 31 | } 32 | 33 | var level = 0; 34 | var pos = -1; 35 | var priority = 0; 36 | 37 | for (var i = l; i < r; ++i) { 38 | switch (str[i]) { 39 | case '(': 40 | ++level; 41 | break; 42 | case ')': 43 | --level; 44 | break; 45 | case '&': 46 | if (level == 0 && priority < 3) { 47 | priority = 3; 48 | pos = i; 49 | } 50 | break; 51 | case '|': 52 | if (level == 0 && priority < 2) { 53 | priority = 2; 54 | pos = i; 55 | } 56 | break; 57 | case '~': 58 | if (level == 0 && priority < 4) { 59 | priority = 4; 60 | pos = i; 61 | } 62 | break; 63 | case '^': 64 | if (level == 0 && priority < 1) { 65 | priority = 1; 66 | pos = i; 67 | } 68 | break; 69 | } 70 | } 71 | 72 | if (pos == -1 && str[l] == '(' && str[r - 1] == ')') { 73 | this.parse(str, l + 1, r - 1); 74 | } else if (pos == -1) { 75 | this.type = 'var'; 76 | this.right = str.substr(l, r - l).trim(); 77 | } else { 78 | this.type = str.substr(pos, 1); 79 | this.left = new Expression(); 80 | this.left.parse(str, l, pos); 81 | this.right = new Expression(); 82 | this.right.parse(str, pos + 1, r); 83 | } 84 | }; 85 | 86 | Expression.prototype.output = function (varibales, map, bit) { 87 | switch (this.type) { 88 | case 'var': 89 | if (map[this.right]) { 90 | return map[this.right].output(varibales, map, bit); 91 | } else if (varibales[this.right]) { 92 | return varibales[this.right].output(bit); 93 | } 94 | return ''; 95 | case '&': 96 | if (bit) { 97 | return '' + this.left.output(varibales, map, bit) + this.right.output(varibales, map, bit) + ''; 98 | } else { 99 | return '' + this.left.output(varibales, map, bit) + this.right.output(varibales, map, bit) + ''; 100 | } 101 | case '|': 102 | if (bit) { 103 | return '' + this.left.output(varibales, map, bit) + this.right.output(varibales, map, bit) + ''; 104 | } else { 105 | return '' + this.left.output(varibales, map, bit) + this.right.output(varibales, map, bit) + ''; 106 | } 107 | case '~': 108 | return this.right.output(varibales, map, !bit); 109 | case '^': 110 | if (bit) { 111 | return '' + this.left.output(varibales, map, bit) + this.right.output(varibales, map, bit) + 112 | '' + this.left.output(varibales, map, !bit) + this.right.output(varibales, map, !bit) + ''; 113 | } else { 114 | return '' + this.left.output(varibales, map, bit) + this.right.output(varibales, map, bit) + 115 | '' + this.left.output(varibales, map, !bit) + this.right.output(varibales, map, !bit) + ''; 116 | } 117 | default : 118 | return ''; 119 | } 120 | }; 121 | 122 | function Scope() { 123 | this.variables = {}; 124 | this.map = {}; 125 | } 126 | 127 | Scope.prototype.genCSS = function () { 128 | var CSS0 = '', CSS1 = ''; 129 | for (var i in this.variables) { 130 | if (CSS0) { 131 | CSS0 += ','; 132 | } 133 | CSS0 += '#cc-input-' + i + ':not(:checked)~.cc-container .cc.cc-1-' + i; 134 | CSS0 += ', #cc-input-' + i + ':checked~.cc-container .cc.cc-0-' + i; 135 | if (CSS1) { 136 | CSS1 += ','; 137 | } 138 | CSS1 += '#cc-input-' + i + ':not(:checked)~.cc-container .cc.cc-0-' + i; 139 | CSS1 += ', #cc-input-' + i + ':checked~.cc-container .cc.cc-1-' + i; 140 | } 141 | CSS0 += '{width:0}'; 142 | CSS1 += '{width:10px}'; 143 | return CSS0 + CSS1; 144 | }; 145 | 146 | Scope.prototype.genHTML = function () { 147 | 148 | }; 149 | 150 | Scope.prototype.addVariable = function (name) { 151 | this.variables[name] = new Variable(); 152 | this.variables[name].set(name); 153 | }; 154 | 155 | Scope.prototype.addMap = function (name, str) { 156 | this.map[name] = new Expression(); 157 | this.map[name].parse(str, 0, str.length); 158 | }; 159 | 160 | function Parser(scope) { 161 | this.scope = scope; 162 | } 163 | 164 | Parser.prototype.parseLine = function (str) { 165 | var self = this; 166 | var expression = str.toLowerCase().trim(); 167 | 168 | var testDeclaration = expression.match(/^var (.+);$/); 169 | if (testDeclaration !== null) { 170 | // Declaration variables 171 | var variables = testDeclaration[1].split(','); 172 | variables.forEach(function (variable) { 173 | self.scope.addVariable(variable.trim()); 174 | }); 175 | } else { 176 | // Expression 177 | var assignment = expression.match(/^(.+)=(.+);$/); 178 | self.scope.addMap(assignment[1], assignment[2]); 179 | } 180 | }; 181 | 182 | window.cc = { 183 | Variable: Variable, 184 | Expression: Expression, 185 | Scope: Scope, 186 | Parser: Parser 187 | }; 188 | })(window); 189 | --------------------------------------------------------------------------------