From 52d4cf8772d304aa9722939151003c9b935f4138 Mon Sep 17 00:00:00 2001 From: redouane-bensaci Date: Sat, 22 Feb 2025 18:16:48 +0100 Subject: [PATCH 01/12] labels added --- package-lock.json | 252 +++++---------------------- package.json | 1 + src/App.js | 3 +- src/assembler/Assembler.js | 17 +- src/assembler/Lexer.js | 278 +++++++++++++++--------------- src/assembler/SemanticAnalysis.js | 96 +++++------ src/pages/Ide/index.jsx | 1 + 7 files changed, 248 insertions(+), 400 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f970b7..38d8530 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@uiw/react-codemirror": "^4.19.9", "aos": "^2.3.4", "axios": "^1.4.0", + "codemirror": "^5.65.18", "framer-motion": "^10.3.1", "gsap": "^3.11.5", "prop-types": "^15.8.1", @@ -4234,25 +4235,6 @@ "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/@testing-library/dom": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.2.0.tgz", - "integrity": "sha512-xTEnpUKiV/bMyEsE5bT4oYA0x0Z/colMtxzUY8bKyPXBNLn/e0V4ZjBZkEhms0xE4pv9QsPfSRu9AWS4y5wGvA==", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/@testing-library/jest-dom": { "version": "5.16.5", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", @@ -6987,10 +6969,9 @@ } }, "node_modules/codemirror": { - "version": "5.65.12", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.12.tgz", - "integrity": "sha512-z2jlHBocElRnPYysN2HAuhXbO3DNB0bcSKmNz3hcWR2Js2Dkhc1bEOxG93Z3DeUrnm+qx56XOY5wQmbP5KY0sw==", - "peer": true + "version": "5.65.18", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.18.tgz", + "integrity": "sha512-Gaz4gHnkbHMGgahNt3CA5HBk5lLQBqmD/pBgeB4kQU6OedZmqMBjlRF0LSrp2tJ4wlLNPm2FfaUd1pDy0mdlpA==" }, "node_modules/collect-v8-coverage": { "version": "1.0.1", @@ -17198,35 +17179,6 @@ "wl-msg-reader": "^0.2.0" } }, - "node_modules/react-doc-viewer/node_modules/react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-doc-viewer/node_modules/react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" - }, - "peerDependencies": { - "react": "^16.14.0" - } - }, "node_modules/react-doc-viewer/node_modules/react-pdf": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-5.0.0.tgz", @@ -17248,16 +17200,6 @@ "react-dom": "^16.3.0" } }, - "node_modules/react-doc-viewer/node_modules/scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -20771,19 +20713,6 @@ "is-typedarray": "^1.0.0" } }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "node_modules/ua-parser-js": { "version": "1.0.35", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz", @@ -23871,14 +23800,12 @@ "@csstools/postcss-unset-value": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", - "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", - "requires": {} + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==" }, "@csstools/selector-specificity": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", - "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", - "requires": {} + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==" }, "@cyntler/react-doc-viewer": { "version": "1.13.0", @@ -24042,8 +23969,7 @@ "@emotion/use-insertion-effect-with-fallbacks": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", - "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", - "requires": {} + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==" }, "@emotion/utils": { "version": "1.2.0", @@ -25003,8 +24929,7 @@ "@mui/types": { "version": "7.2.4", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", - "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", - "requires": {} + "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==" }, "@mui/utils": { "version": "5.12.0", @@ -25292,22 +25217,6 @@ "loader-utils": "^2.0.0" } }, - "@testing-library/dom": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.2.0.tgz", - "integrity": "sha512-xTEnpUKiV/bMyEsE5bT4oYA0x0Z/colMtxzUY8bKyPXBNLn/e0V4ZjBZkEhms0xE4pv9QsPfSRu9AWS4y5wGvA==", - "peer": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - } - }, "@testing-library/jest-dom": { "version": "5.16.5", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", @@ -26229,14 +26138,12 @@ "acorn-import-assertions": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "requires": {} + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==" }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" }, "acorn-walk": { "version": "7.2.0", @@ -26279,8 +26186,7 @@ "ajv-errors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "requires": {} + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" }, "ajv-formats": { "version": "2.1.1", @@ -26311,8 +26217,7 @@ "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" }, "ansi-escapes": { "version": "4.3.2", @@ -26723,8 +26628,7 @@ "babel-plugin-named-asset-import": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", - "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", - "requires": {} + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==" }, "babel-plugin-polyfill-corejs2": { "version": "0.3.3", @@ -27495,10 +27399,9 @@ } }, "codemirror": { - "version": "5.65.12", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.12.tgz", - "integrity": "sha512-z2jlHBocElRnPYysN2HAuhXbO3DNB0bcSKmNz3hcWR2Js2Dkhc1bEOxG93Z3DeUrnm+qx56XOY5wQmbP5KY0sw==", - "peer": true + "version": "5.65.18", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.18.tgz", + "integrity": "sha512-Gaz4gHnkbHMGgahNt3CA5HBk5lLQBqmD/pBgeB4kQU6OedZmqMBjlRF0LSrp2tJ4wlLNPm2FfaUd1pDy0mdlpA==" }, "collect-v8-coverage": { "version": "1.0.1", @@ -27868,8 +27771,7 @@ "css-declaration-sorter": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz", - "integrity": "sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew==", - "requires": {} + "integrity": "sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew==" }, "css-has-pseudo": { "version": "3.0.4", @@ -27952,8 +27854,7 @@ "css-prefers-color-scheme": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", - "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", - "requires": {} + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==" }, "css-select": { "version": "4.3.0", @@ -28067,8 +27968,7 @@ "cssnano-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "requires": {} + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==" }, "csso": { "version": "4.2.0", @@ -29057,8 +28957,7 @@ "eslint-plugin-react-hooks": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "requires": {} + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==" }, "eslint-plugin-testing-library": { "version": "5.10.3", @@ -30464,8 +30363,7 @@ "icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "requires": {} + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==" }, "idb": { "version": "7.1.1", @@ -31740,8 +31638,7 @@ "jest-pnp-resolver": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "requires": {} + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==" }, "jest-regex-util": { "version": "27.5.1", @@ -34132,8 +34029,7 @@ "postcss-browser-comments": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", - "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", - "requires": {} + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==" }, "postcss-calc": { "version": "8.2.4", @@ -34231,26 +34127,22 @@ "postcss-discard-comments": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "requires": {} + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==" }, "postcss-discard-duplicates": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "requires": {} + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==" }, "postcss-discard-empty": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "requires": {} + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==" }, "postcss-discard-overridden": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "requires": {} + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==" }, "postcss-double-position-gradients": { "version": "3.1.2", @@ -34272,8 +34164,7 @@ "postcss-flexbugs-fixes": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", - "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", - "requires": {} + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==" }, "postcss-focus-visible": { "version": "6.0.4", @@ -34294,14 +34185,12 @@ "postcss-font-variant": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", - "requires": {} + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==" }, "postcss-gap-properties": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", - "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", - "requires": {} + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==" }, "postcss-image-set-function": { "version": "4.0.7", @@ -34324,8 +34213,7 @@ "postcss-initial": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", - "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", - "requires": {} + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==" }, "postcss-js": { "version": "4.0.1", @@ -34366,14 +34254,12 @@ "postcss-logical": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", - "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", - "requires": {} + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==" }, "postcss-media-minmax": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", - "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", - "requires": {} + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==" }, "postcss-merge-longhand": { "version": "5.1.7", @@ -34434,8 +34320,7 @@ "postcss-modules-extract-imports": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "requires": {} + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==" }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -34493,8 +34378,7 @@ "postcss-normalize-charset": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "requires": {} + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==" }, "postcss-normalize-display-values": { "version": "5.1.0", @@ -34565,8 +34449,7 @@ "postcss-opacity-percentage": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", - "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", - "requires": {} + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==" }, "postcss-ordered-values": { "version": "5.1.3", @@ -34588,8 +34471,7 @@ "postcss-page-break": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", - "requires": {} + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==" }, "postcss-place": { "version": "7.0.5", @@ -34683,8 +34565,7 @@ "postcss-replace-overflow-wrap": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", - "requires": {} + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==" }, "postcss-selector-not": { "version": "6.0.1", @@ -35072,8 +34953,7 @@ "react-codemirror2": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/react-codemirror2/-/react-codemirror2-7.2.1.tgz", - "integrity": "sha512-t7YFmz1AXdlImgHXA9Ja0T6AWuopilub24jRaQdPVbzUJVNKIYuy3uCFZYa7CE5S3UW6SrSa5nAqVQvtzRF9gw==", - "requires": {} + "integrity": "sha512-t7YFmz1AXdlImgHXA9Ja0T6AWuopilub24jRaQdPVbzUJVNKIYuy3uCFZYa7CE5S3UW6SrSa5nAqVQvtzRF9gw==" }, "react-dev-utils": { "version": "12.0.1", @@ -35124,29 +35004,6 @@ "wl-msg-reader": "^0.2.0" }, "dependencies": { - "react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "peer": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - } - }, - "react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "peer": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" - } - }, "react-pdf": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-5.0.0.tgz", @@ -35160,16 +35017,6 @@ "prop-types": "^15.6.2", "worker-loader": "^3.0.0" } - }, - "scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "peer": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } } } }, @@ -35212,8 +35059,7 @@ "pdfjs-dist": { "version": "2.12.313", "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.12.313.tgz", - "integrity": "sha512-1x6iXO4Qnv6Eb+YFdN5JdUzt4pAkxSp3aLAYPX93eQCyg/m7QFzXVWJHJVtoW48CI8HCXju4dSkhQZwoheL5mA==", - "requires": {} + "integrity": "sha512-1x6iXO4Qnv6Eb+YFdN5JdUzt4pAkxSp3aLAYPX93eQCyg/m7QFzXVWJHJVtoW48CI8HCXju4dSkhQZwoheL5mA==" } } }, @@ -37246,8 +37092,7 @@ "style-loader": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.2.tgz", - "integrity": "sha512-RHs/vcrKdQK8wZliteNK4NKzxvLBzpuHMqYmUVWeKa6MkaIQ97ZTOS0b+zapZhy6GcrgWnvWYCMHRirC3FsUmw==", - "requires": {} + "integrity": "sha512-RHs/vcrKdQK8wZliteNK4NKzxvLBzpuHMqYmUVWeKa6MkaIQ97ZTOS0b+zapZhy6GcrgWnvWYCMHRirC3FsUmw==" }, "style-mod": { "version": "4.0.3", @@ -37903,12 +37748,6 @@ "is-typedarray": "^1.0.0" } }, - "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true - }, "ua-parser-js": { "version": "1.0.35", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz", @@ -38107,8 +37946,7 @@ "use-isomorphic-layout-effect": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", - "requires": {} + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==" }, "util": { "version": "0.11.1", @@ -38647,8 +38485,7 @@ "ws": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "requires": {} + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==" } } }, @@ -39105,8 +38942,7 @@ "ws": { "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "requires": {} + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==" }, "xml-name-validator": { "version": "3.0.0", diff --git a/package.json b/package.json index b222668..ab4521c 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@uiw/react-codemirror": "^4.19.9", "aos": "^2.3.4", "axios": "^1.4.0", + "codemirror": "^5.65.18", "framer-motion": "^10.3.1", "gsap": "^3.11.5", "prop-types": "^15.8.1", diff --git a/src/App.js b/src/App.js index 88a99bc..c49189c 100644 --- a/src/App.js +++ b/src/App.js @@ -47,7 +47,8 @@ function App() { - }/> + + }/> }/> }/> }/> diff --git a/src/assembler/Assembler.js b/src/assembler/Assembler.js index 7863042..99beebd 100644 --- a/src/assembler/Assembler.js +++ b/src/assembler/Assembler.js @@ -202,12 +202,15 @@ while (hexString.length < size) { Label_To_Num : (labelname,linenumber)=>{ var labelobj = false ; - Assembler.Labellist.forEach(element => { - if(element.name === labelname){ - labelobj = element - } + console.log(Assembler.Labellist) + console.log(labelname) + labelobj = Assembler.Labellist.find(element => { + console.log(element.name) + console.log(labelname) + console.log(element.name === labelname) + return element.name === labelname; }); - //console.log(labelobj) + console.log(labelobj) if (labelobj == false) { //error @@ -215,6 +218,7 @@ while (hexString.length < size) { return {type: 'ERROR', value: null}; }else{ //return the address + console.log(labelobj) return {type: 'NUMBER', value: labelobj.address} }}, @@ -894,6 +898,7 @@ export class Assembler{ + console.log("\nLabel list: \n",Assembler.Labellist) //var input = ["MOV 0,0"] @@ -907,8 +912,6 @@ let output = new Assembler(input) ; -console.log("\nLabel list: \n",Assembler.Labellist) - //console.log("\nSemantic list: \n", output?.toAssemble?.Semanticlist ?? "Semanticlist is undefined"); console.log("\nSemantic list: \n", (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"); var toassmb = (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"; diff --git a/src/assembler/Lexer.js b/src/assembler/Lexer.js index e21bd31..49ac01d 100644 --- a/src/assembler/Lexer.js +++ b/src/assembler/Lexer.js @@ -1,151 +1,157 @@ import { Assembler } from './Assembler.js'; import { Errorcalm } from './Errorcalm.js'; import { SemanticAnalysis } from './SemanticAnalysis.js'; + export class Lexer { static Errors = []; - + static isValidString(str) { // Check if the string contains any special characters if (/[^a-zA-Z0-9_]/.test(str)) { return false; - }else{ - - // Check if the string begins with a number - if (/^\d/.test(str)) { - return false; - }else{ - // Check if the string is in the excluded list - if (Assembler.excludedStrings.includes(str)) { - return false; - }else{ - // If none of the above conditions are met, the string is valid ; - //console.log("valid string") - return true; + } else { + // Check if the string begins with a number + if (/^\d/.test(str)) { + return false; + } else { + // Check if the string is in the excluded list + if (Assembler.excludedStrings.includes(str)) { + return false; + } else { + // If none of the above conditions are met, the string is valid + return true; + } + } } - }} } - constructor(code,line) { - //console.log(code.match(/([a-zA-Z0-9]+\d*(?:[a-zA-Z09]+)?|\*|,|\+)/g)) - this.LexicalList = code.match(/([a-zA-Z0-9]+\d*(?:[a-zA-Z0-9]+)?|\*|,|\+,,|\~|,|\`|,|\!|,|\@|,|\#|,|\$|,|\-|,|\%|,|\^|,|\&|,|\*|,|\(|,|\)|,|\_|,|\=|,|\+|,|\[|,|\]|,|\{|,|\}|,|\;|,|\:|,|\'|,|\"|,|\,|,|\.|,|\<|,|\>|,|\?|,|\\|)/g).filter(function (t) { - return t.length > 0; - }).map((t,index)=> { - if (isNaN(t)) { - switch (t) { - case 'R1': - case 'R2': - case 'R3': - case 'R4': - case 'ACC': - case 'BR': - case 'IDR': - case 'SR': - case 'R1R': - case 'R2R': - case 'R3R': - case 'ACCR': - case 'R1L': - case 'R2L': - case 'R3L': - case 'ACCL': - return { - type: 'REGISTER', - value: t - }; - case 'RET': - case 'PUSHA': - case 'POPA': - return{ - type: 'INST0', - value: t - }; - case 'NEG': - case 'NOT': - case 'SHL': - case 'SHR': - case 'READ': - case 'WRITE': - case 'PUSH': - case 'POP': - case 'ROR': - case 'ROL': - case 'CALL': - case 'BE': - case 'BNE': - case 'BS': - case 'BI': - case 'BIE': - case 'BSE': - case 'BRI': - return { - type: 'INST1', - value: t - }; - case 'NAND': - case 'CMP': - case 'MOV': - case 'ADD': - case 'SUB': - case 'MUL': - case 'DIV': - case 'AND': - case 'OR': - case 'XOR': - case 'NOR': - return{ - type: 'INST2', - value: t - }; - case '*': - case ',': - case '+': - case '-': - return { - type: 'SPECIAL CHARACTER', - value: t - }; - case 'LABEL': - return { - type: 'LABEL' - }; - break; + + constructor(code, line) { + this.LexicalList = code.match(/([a-zA-Z0-9]+\d*(?:[a-zA-Z0-9]+)?)(:?)|\*|,|\+,,|\~|,|\|,|\!|,|\@|,|\#|,|\$|,|\-|,|\%|,|\^|,|\&|,|\*|,|\(|,|\)|,|\_|,|\=|,|\+|,|\[|,|\]|,|\{|,|\}|,|\;|,|\:|,|\'|,|\"|,|\,|,|\.|,|\<|,|\>|,|\?|,|\\|/g).filter(function (t) { + return t.length > 0; + }).flatMap((t, index) => { + if (isNaN(t)) { + switch (t) { + case 'R1': + case 'R2': + case 'R3': + case 'R4': + case 'ACC': + case 'BR': + case 'IDR': + case 'SR': + case 'R1R': + case 'R2R': + case 'R3R': + case 'ACCR': + case 'R1L': + case 'R2L': + case 'R3L': + case 'ACCL': + return [{ + type: 'REGISTER', + value: t + }]; + case 'RET': + case 'PUSHA': + case 'POPA': + return [{ + type: 'INST0', + value: t + }]; + case 'NEG': + case 'NOT': + case 'SHL': + case 'SHR': + case 'READ': + case 'WRITE': + case 'PUSH': + case 'POP': + case 'ROR': + case 'ROL': + case 'CALL': + case 'BE': + case 'BNE': + case 'BS': + case 'BI': + case 'BIE': + case 'BSE': + case 'BRI': + return [{ + type: 'INST1', + value: t + }]; + case 'NAND': + case 'CMP': + case 'MOV': + case 'ADD': + case 'SUB': + case 'MUL': + case 'DIV': + case 'AND': + case 'OR': + case 'XOR': + case 'NOR': + return [{ + type: 'INST2', + value: t + }]; + case '*': + case ',': + case '+': + case '-': + return [{ + type: 'SPECIAL CHARACTER', + value: t + }]; + case 'LABEL': + return [{ + type: 'LABEL' + }]; default: - if (Lexer.isValidString(t)) { - return { - type: 'TEXT', - value: t - }; - }else{ - Lexer.Errors.push(new Errorcalm("Invalid string", "LEXER", line)) ; //change this 0 to the line number - Errorcalm.set_LexicalError(new Errorcalm("Invalid string", "LEXER", line)); - } - } - } else { - return { - type: 'NUMBER', - value: t - }; - } - }); - let lexlist= this.LexicalList - lexlist.forEach((element,index,lexlist) => { - if (element.type =='NUMBER') { - if ( lexlist[index-1].value=='-' && lexlist[index-1].type=='SPECIAL CHARACTER' ){ - console.log( '-'+element.value ) - lexlist.splice(index-1, 1); - if( parseInt('-'+element.value,10) < -32768){ - Lexer.Errors.push(new Errorcalm("Number out of range", "LEXER", line)) ; //change this 0 to the line number - Errorcalm.set_LexicalError(new Errorcalm("Number out of range", "LEXER", line)); - }else{ - lexlist[index-1]={ - type: 'NUMBER' - ,value: `-${element.value}` - }} + if (t.endsWith(':')) { + let labelText = t.slice(0, -1).trim(); // Extract label text + + return [ + { type: 'LABEL' }, + { type: 'TEXT', value: labelText }, + { type: 'NUMBER', value: line.toString() } + ]; + } + else if (Lexer.isValidString(t)) { + return [{ type: 'TEXT', value: t }]; + } else { + Lexer.Errors.push(new Errorcalm("Invalid string", "LEXER", line)); + Errorcalm.set_LexicalError(new Errorcalm("Invalid string", "LEXER", line)); + return []; + } } + } else { + return [{ + type: 'NUMBER', + value: t + }]; } - - }); - this.LexicalList = lexlist; - - } + }); - } \ No newline at end of file + // Flatten the array of arrays into a single array + let lexlist = this.LexicalList.flat(); + lexlist.forEach((element, index, lexlist) => { + if (element.type == 'NUMBER') { + if (lexlist[index - 1].value == '-' && lexlist[index - 1].type == 'SPECIAL CHARACTER') { + console.log('-' + element.value); + lexlist.splice(index - 1, 1); + if (parseInt('-' + element.value, 10) < -32768) { + Lexer.Errors.push(new Errorcalm("Number out of range", "LEXER", line)); + Errorcalm.set_LexicalError(new Errorcalm("Number out of range", "LEXER", line)); + } else { + lexlist[index - 1] = { + type: 'NUMBER', + value: `-${element.value}` + }; + } + } + } + }); + this.LexicalList = lexlist; + } +} \ No newline at end of file diff --git a/src/assembler/SemanticAnalysis.js b/src/assembler/SemanticAnalysis.js index c5845d0..29c8799 100644 --- a/src/assembler/SemanticAnalysis.js +++ b/src/assembler/SemanticAnalysis.js @@ -9,6 +9,52 @@ export class SemanticAnalysis { constructor(input) { let lexicalList = input; + for(let i = 0; i < lexicalList.length; i++){ + + let firstword = lexicalList[i][0] + let firstwordtype = firstword.type + if (firstwordtype == 'LABEL') { + if (lexicalList[i].length == 3) { + if (lexicalList[i][2].type == 'NUMBER') { + if( lexicalList[i][2].value < Assembler.MAXNUM){ + if(lexicalList[i][1].type == 'TEXT'){ + if(Lexer.isValidString(lexicalList[i][1].value)){ + // filters for text standards and validity of the text + // check if label already existing + var found = false ; + var labelname = lexicalList[i][1].value ; + Assembler.Labellist.forEach(element => { + if(element.name === labelname){ + found = true + } + }); + if (!found) { + //this.Semanticlist.push(lexicalList[i]); + //stop pushing here because we don't need it + Assembler.Labellist.push({ name: labelname, address: lexicalList[i][2].value, linedeclared:i }) + }else{ + this.Semanticlist.push(new Errorcalm("LABEL already declared",null,i)) + } + }else{ this.Semanticlist.push(new Errorcalm("LABEL name is not valid",null,i)) } + }else{ + this.Semanticlist.push(new Errorcalm("LABEL name not defined",null,i)) + } + }else{ + this.Semanticlist.push(new Errorcalm("Number size is bigger then MAXNUM",null,i)) + } + }else{ + this.Semanticlist.push(new Errorcalm("LABEL must be a number",null,i)) + } + }else{ + if (Lexer.isValidString(lexicalList[i][2].value )) { + this.Semanticlist.push(new Errorcalm("LABEL must have only two operands",null,i)) + }else + { + this.Semanticlist.push(new Errorcalm("LABEL name is not valid",null,i)) + } + } + } + } for(let i = 0; i < lexicalList.length; i++){ // here operation with each line of code // we must check if it is a label or an instruction @@ -17,54 +63,8 @@ export class SemanticAnalysis { let firstword = lexicalList[i][0] let firstwordtype = firstword.type - - switch (firstwordtype) { - - case 'LABEL': - const functLABEL = ()=> { - if (lexicalList[i].length == 3) { - if (lexicalList[i][2].type == 'NUMBER') { - if( lexicalList[i][2].value < Assembler.MAXNUM){ - if(lexicalList[i][1].type == 'TEXT'){ - if(Lexer.isValidString(lexicalList[i][1].value)){ - // filters for text standards and validity of the text - // check if label already existing - var found = false ; - var labelname = firstword.value ; - Assembler.Labellist.forEach(element => { - if(element.name === labelname){ - found = true - } - }); - if (!found) { - //this.Semanticlist.push(lexicalList[i]); - //stop pushing here because we don't need it - Assembler.Labellist.push({ name: lexicalList[i][1].value, address: lexicalList[i][2].value, linedeclared:i }) - }else{ - this.Semanticlist.push(new Errorcalm("LABEL already declared",null,i)) - } - }else{ this.Semanticlist.push(new Errorcalm("LABEL name is not valid",null,i)) } - }else{ - this.Semanticlist.push(new Errorcalm("LABEL name not defined",null,i)) - } - }else{ - this.Semanticlist.push(new Errorcalm("Number size is bigger then MAXNUM",null,i)) - }}else{ - this.Semanticlist.push(new Errorcalm("LABEL must be a number",null,i)) - } - }else{ - if (Lexer.isValidString(lexicalList[i][2].value )) { - this.Semanticlist.push(new Errorcalm("LABEL must have only two operands",null,i)) - }else - { - this.Semanticlist.push(new Errorcalm("LABEL name is not valid",null,i)) - } - } - } - - functLABEL(); - break; - + + switch (firstwordtype) { case 'INST0': // No params instructions: INST0 ::= RET, PUSHA, POPA // We must have no op after it diff --git a/src/pages/Ide/index.jsx b/src/pages/Ide/index.jsx index e18c69d..70cf5ce 100644 --- a/src/pages/Ide/index.jsx +++ b/src/pages/Ide/index.jsx @@ -335,6 +335,7 @@ const Ide = ({currentUser})=>{ let inputouter=[]; if(iscode){ + console.log(handleStoreCode) inputouter=Assembler.assemblecode(handleStoreCode()) }else{ inputouter=handleStoreCode(); From be563aa9fcb588cbbcf9f377602c5721df8255c6 Mon Sep 17 00:00:00 2001 From: nejem Eddine Mekentichi <83135662+Nejmeddine-Mek@users.noreply.github.com> Date: Sun, 2 Mar 2025 23:43:41 +0100 Subject: [PATCH 02/12] handling macros, finding data segment and detecting labels, no errors are thrown yet, but they are mentioned --- Calm | 1 + src/assembler/preprocessing.js | 192 +++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 160000 Calm create mode 100644 src/assembler/preprocessing.js diff --git a/Calm b/Calm new file mode 160000 index 0000000..6f82cba --- /dev/null +++ b/Calm @@ -0,0 +1 @@ +Subproject commit 6f82cbaffeea10c8da04d6ff673f5ac5ebaf5c03 diff --git a/src/assembler/preprocessing.js b/src/assembler/preprocessing.js new file mode 100644 index 0000000..9f34c97 --- /dev/null +++ b/src/assembler/preprocessing.js @@ -0,0 +1,192 @@ + +class preprocessing{ + static keyWords = ['MACRO', 'ENDM', 'START', 'END'] + static DataKeyword = ['SDATA', 'ENDS'] + constructor(){ + this.MACROS = [] + this.macroKeyWord = new Set() + this.labelSymbolList = [] + this.dataSegment = [] + } + + getDataSegment(code){ + const n = code.length + for(let i = 0; i < n ; i++){ + + if(code[i] === 'SDATA'){ + i += 1 + let endOfSeg = false + while(!endOfSeg){ + if(code[i] === 'ENDS'){ + endOfSeg = true + continue + } + if(i === n){ + //error segment not closed + return + } + this.dataSegment.push(code[i++]) + } + break + } + } + console.log('data: ', this.dataSegment) + } + // remove static from all methods below, cuz we are acting on objects + static removeComments(code){ //removes comments from all code as well as empty lines + console.log(typeof(code)) + code = code.toUpperCase().split('\n') + + const output = [] + const n = code.length + + for(let i = 0; i < n; i++){ + let temp = code[i].split('//') + if(temp[0] === '' || temp[0].trim(' ','') === ''){ + continue + } + + if(temp.length === 1){ + + output.push(temp[0].trim()) + continue + } + + output.push(temp[0].trim()) + } + return output + } + // we suppose the code is given to use as + extractMacro(input /*it should be the whole code */){ + // input is the whole code which we divided into an array of strings + let curLine = 0 + let n = input.length + while(curLine < n && input[curLine] !== 'START' ){ + let line = input[curLine].match(/([a-zA-Z_][a-zA-Z0-9_]*|[,:])/g) + if(line[0] === 'MACRO'){ + let macroClosed = false + this.macroKeyWord.add(line[1]) + let macroHolder = {keyWord: line[1], instruction: line.slice(1), body : []} + curLine += 1 + // this whole thing must be foxed later + while(!macroClosed){ + if(!input[curLine]){ + console.log("not closed, and main function not declared") + return + } + if(input[curLine] === 'START'){ + console.log("code starts and macro not closed") + return + } + if(input[curLine] === 'ENDM'){ + macroClosed = true + continue + } + line = input[curLine++].match(/([a-zA-Z_][a-zA-Z0-9_]*|[,:])/g) + macroHolder.body.push(line) + } + this.MACROS.push(macroHolder) + } + + curLine += 1 // move to next line + } + this.MACROS.forEach(macro => console.log(macro)) + } + // this method should remove extra text from top as well as macros and start / end keywords? + replaceMacro(input /*it should be also the whole code */){ + let output = [] // new code will be returned here + let curLine = 0 + let endOfCode = false + while(input[curLine] !== 'START'){ + curLine += 1 + if(!input[curLine]){ + // throw error + return + } + } + curLine += 1 + while(!endOfCode){ + if(!input[curLine]){ + // throw error and quit + return {error: "this thing doesn't work"} + } + if(input[curLine] === 'END'){ + endOfCode = true + continue + } + let line = input[curLine++].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|,)/g) + + if(line[0][line[0].length - 1] === ':'){ + if(this.macroKeyWord.has(line[1])){ + // expand macro + // replaceMacro(line,output) // pushes directly in the output code + output.push( ...this.expandMacro(line,line[1],true)) + //output.push('this is a macro') + } + } else if(this.macroKeyWord.has(line[0])){ + // replace again + output.push( ...this.expandMacro(line,line[0])) + //output.push('this is a macro') + } else { + output.push(input[curLine - 1]) + } + } + return output + } + + + expandMacro(line,keyWord,label = false){ + + const [ expandedMacroTemplate ]= this.MACROS.filter(macro => macro.keyWord === keyWord) + let body = expandedMacroTemplate.body.map(line => line.join(' ')) + let newLine = line + // now we check the line, and replace args where needed + if(label){ + // handle when there is a label + // this will work the opposite way + body[0] = line[0] + ' ' + body[0] + newLine = line.filter(word => word[word.length - 1] !== ':') + } + if(newLine.length !== expandedMacroTemplate.instruction.length){ + //throw error, different number of args + return ["error here"] + } + //there is no label, direct matching + for(let i = newLine.length - 1; i >= 1; i--){ + + body = body.map(inst => inst.replace(expandedMacroTemplate.instruction[i], newLine[i])) + + } + return body + } + // no errors are handled here + // no spaces allowed between labelName and : + detectLabels(code /* */){ + let n = code.length + for(let i = 0; i < n; i++){ + let line = code[i].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|,)/g) + if(line[0][line[0].length - 1] === ":"){ + if(line[0].length === 1){ + // throw error + console.log("error, empty label") + return + } + this.labelSymbolList.push({label: line[0].slice(0,-1), line: i + 1}) + } + } + console.log(this.labelSymbolList) + } + + removeAndReplaceLabels(code){ + // replace labels with their line numbers I guess + let n = code.length + let output = [] + for(let i = 0; i < n; i++){ + //check in each line if there is a use of the label, if definition, we remove it, if use, replace with line number + } + } + +} + + +module.exports = { preprocessing } \ No newline at end of file From 4be7065f1217d4b3eb18e9d2eb690e02654cf734 Mon Sep 17 00:00:00 2001 From: redouane-bensaci Date: Thu, 13 Mar 2025 02:55:40 +0100 Subject: [PATCH 03/12] LABELS are now fully supported --- src/Emulator/ALU.js | 51 ++--------- src/Emulator/IO_Unit.js | 1 - src/Emulator/MC.js | 1 + src/Emulator/Queue.js | 1 + src/Emulator/Sequencer.js | 13 ++- src/assembler/Assembler.js | 88 +++++++++---------- src/assembler/Errorcalm.js | 1 - src/assembler/Lexer.js | 6 +- src/assembler/SemanticAnalysis.js | 33 ++++--- src/components/AdressingModeListing/index.jsx | 1 - src/components/AuthForm/index.jsx | 5 +- src/components/ComponentsListing/index.jsx | 3 +- src/components/ProgramContainer/index.jsx | 5 +- src/components/SaveCodeButton/index.jsx | 7 +- src/pages/Ide/index.jsx | 1 + 15 files changed, 89 insertions(+), 128 deletions(-) diff --git a/src/Emulator/ALU.js b/src/Emulator/ALU.js index 1792340..be643c8 100644 --- a/src/Emulator/ALU.js +++ b/src/Emulator/ALU.js @@ -124,7 +124,6 @@ class Alu{ subBinary(size){ //get the two's complement of the content of the RUAL2: - console.log("RUAL2 Value befor anything "+this.Rual2.value); //than the one's complement of the result : let i=this.Rual2.value.length-1; @@ -136,19 +135,14 @@ class Alu{ i--; } this.Rual2.setvalue(b); - console.log("Ones complement of RUAL2 "+this.Rual2.value); - - //first we add (RAL2)+1 + //first we add (RAL2)+1 let x=1; let res1=parseInt(this.Rual2.getvalue(),2); res1=res1+x; this.Rual2.setvalue(fullzero(size,res1.toString(2))); b=this.Rual2.getvalue()//very important on overflow detection - console.log("Tows complement of RUAL2 "+this.Rual2.value); //then the simple binary addition between RUAL1 and RUAL2: - this.addBinary(size) - console.log("The result of subsrtaction "+ this.Acc.getvalue()); - + this.addBinary(size) //overflow detection: if (this.Rual1.getvalue()[0]!=b[0]) { if (b[0]==this.Acc.getvalue()[0]) { @@ -165,9 +159,7 @@ class Alu{ binaryMultiply(size) { - let binaryString1=(this.Rual1.getvalue()).substring(0,size); - console.log("string1 :"+binaryString1); - + let binaryString1=(this.Rual1.getvalue()).substring(0,size); //two's complement of the abs part of a if(this.Rual1.getvalue()[0]=='1'){ let i=size; @@ -186,9 +178,7 @@ class Alu{ } } let binaryString2=this.Rual2.getvalue().substring(0,size);//verifier - console.log("string2 :"+binaryString2); - - //two's complement of the abs part of b + //two's complement of the abs part of b if(this.Rual2.getvalue()[0]=='1'){ let i=size; let find1=false @@ -207,18 +197,13 @@ class Alu{ } let int1 = parseInt(binaryString1, 2) - console.log(int1) let int2 = parseInt(binaryString2, 2) - console.log(int2) let res= (int1 * int2).toString(2); - console.log(res); if(res.length>=16 ){res=fullzero(32,res)} else{ res=fullzero(16,res)} if (this.Rual1.getvalue()[0]==this.Rual2.getvalue()[0]) { - console.log("positive result") }else{ - console.log("negative result"); let find1=false for (let i = res.length; i >=0; i--) { if(find1==true){ @@ -234,7 +219,6 @@ class Alu{ } } - console.log(res); if(res.length>16){ let resacc=res.substring(16,32); this.Acc.setvalue(resacc); @@ -261,9 +245,7 @@ class Alu{ DivBinary(size){ - let binaryString1=(this.Rual1.getvalue()).substring(1,size); - console.log("string1 :"+binaryString1); - + let binaryString1=(this.Rual1.getvalue()).substring(1,size); //two's complement of the abs part of a if(this.Rual1.getvalue()[0]=='1'){ let i=size; @@ -282,8 +264,6 @@ class Alu{ } } let binaryString2=this.Rual2.getvalue().substring(1,size); - console.log("string2 :"+binaryString2); - //two's complement of the abs part of b if(this.Rual2.getvalue()[0]=='1'){ let i=size; @@ -303,21 +283,15 @@ class Alu{ } let int1 = parseInt(binaryString1, 2) - console.log(int1) let int2 = parseInt(binaryString2, 2) - console.log(int2) let q= (Math.floor(int1 / int2)).toString(2); - console.log("le quotient en valeur absolue :"+q); let r=(int1 % int2).toString(2) q=fullzero(size,q); - console.log("quotient before two's complement "+q); r=fullzero(size,r); //positive or negativ quotient if (this.Rual1.getvalue()[0]==this.Rual2.getvalue()[0]) { - console.log("positive quotient ") - + }else{ - console.log("negative quotient"); let find1=false for (let i =q.length; i >=0; i--) { if(find1==true){ @@ -337,9 +311,7 @@ class Alu{ //positive or negative reste if(this.Rual1.getvalue()[0]=='0') { - console.log("positive reste ") - }else{ - console.log("negative rete"); + }else{ let find1=false for (let i =r.length; i >=0; i--) { if(find1==true){ @@ -361,13 +333,8 @@ class Alu{ //this.Flags[2]=carry.toString();//carry let figure="1" this.Flags[3] = ((this.Acc.value.match(new RegExp(figure, "g")) || []).length %2).toString();//parity - this.Flags[4]=this.Acc.getvalue()[size-1];//p/imp - - console.log("le quotient :" +q); - - console.log("le reste en valeur absolue: "+r); - - this.Acc.setvalue(q); + this.Flags[4]=this.Acc.getvalue()[size-1];//p/imp + this.Acc.setvalue(q); return r; diff --git a/src/Emulator/IO_Unit.js b/src/Emulator/IO_Unit.js index c2d7062..51e1281 100644 --- a/src/Emulator/IO_Unit.js +++ b/src/Emulator/IO_Unit.js @@ -9,7 +9,6 @@ class IOUnit { this.buffer = buffer; } write() { - console.log(this.buffer); } } export default IOUnit; \ No newline at end of file diff --git a/src/Emulator/MC.js b/src/Emulator/MC.js index 46b1c8b..fbb09a1 100644 --- a/src/Emulator/MC.js +++ b/src/Emulator/MC.js @@ -1,3 +1,4 @@ +/* eslint-disable eqeqeq */ import { Register } from "./Register.js" class MC { constructor(){ diff --git a/src/Emulator/Queue.js b/src/Emulator/Queue.js index 6b3db03..0cd9bbf 100644 --- a/src/Emulator/Queue.js +++ b/src/Emulator/Queue.js @@ -220,6 +220,7 @@ class Queue { let mdrval=instruction+instructionpart2; ////// this.instructionBytes.push(instruction); + console.log("something here <3 : \n"+this.instructionBytes) IP.setvalue(TwosComplement(parseInt(IP.getvalue(),2)+1,16)); //animation: if(is_animated){ diff --git a/src/Emulator/Sequencer.js b/src/Emulator/Sequencer.js index 1b56151..5c1d4f9 100644 --- a/src/Emulator/Sequencer.js +++ b/src/Emulator/Sequencer.js @@ -538,13 +538,11 @@ class Sequenceur{ let Inshex=queue.shift(); let Ins=hex2bin(Inshex); this.RI.setvalue(Ins); - console.log(`this is RI here${this.RI.getvalue()}`) - //the animation for this instruction goes here + //the animation for this instruction goes here /////those 2 animations must be at the same time___________________ if(is_animated){ let key=hex2bin(Inshex).substring(0,4); - console.log(key); - if(key>="0010"){//instructions with 1 general byte + if(key>="0010"){//instructions with 1 general byte animations.push({ value:"", nom:"QueueToIr", @@ -2069,7 +2067,7 @@ class Sequenceur{ }) } instrObject.value1=value1; - ///animation from the register to RUAL1 + ///animation from the register to RUAL1 instrObject.value2=value2; }else if(Ind=='10'){ this.getinstrbyte(animations,false,Contextarray); @@ -2375,7 +2373,7 @@ class Sequenceur{ } instrObject.value1=value1; instrObject.value2=value2; - ///animation from the register to RUAL1 + ///animation from the register to RUAL1 }else if(Ind=='11'){ this.getinstrbyte(animations,false,Contextarray); let adresse1=this.RI.getvalue(); @@ -2439,14 +2437,13 @@ class Sequenceur{ } } - return instrObject;} + return instrObject;} } execute(instrObject,is_animated,animations){ let res; for (let i = 0; i < instrObject.stepsNum ; i++) { res = instrObject.steps[i](animations); } - console.log(instrObject); let animationSteps= instrObject.buildanim(); if(is_animated===1 & animationSteps.length>0){ for (let i = 0; i < animationSteps.length; i++) { diff --git a/src/assembler/Assembler.js b/src/assembler/Assembler.js index 99beebd..585d2a5 100644 --- a/src/assembler/Assembler.js +++ b/src/assembler/Assembler.js @@ -1,10 +1,19 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable no-const-assign */ +/* eslint-disable no-useless-escape */ +/* eslint-disable eqeqeq */ +/* eslint-disable no-unreachable */ +/* eslint-disable no-fallthrough */ +/* eslint-disable default-case */ +/* eslint-disable no-redeclare */ import { Lexer } from './Lexer.js'; import {Errorcalm} from './Errorcalm.js' import {SemanticAnalysis} from './SemanticAnalysis.js' +import { element } from 'prop-types'; export const FuncInterface ={ adrmap : (txt,size,dep)=>{ - var adr=''; + var adr='' switch(txt){ case 0: adr = '000'; @@ -189,7 +198,6 @@ while (hexString.length < size) { // binaryToHex: (binaryString,size)=>{ // // Convert decimal to hexadecimal string - // console.log("____________________________"+binaryString+" "+size) // let hexString = parseInt(binaryString, 2).toString(16); // // Pad the hexadecimal string with leading zeros to 4 bytes (8 characters) // while (hexString.length < size) { @@ -202,15 +210,9 @@ while (hexString.length < size) { Label_To_Num : (labelname,linenumber)=>{ var labelobj = false ; - console.log(Assembler.Labellist) - console.log(labelname) labelobj = Assembler.Labellist.find(element => { - console.log(element.name) - console.log(labelname) - console.log(element.name === labelname) return element.name === labelname; }); - console.log(labelobj) if (labelobj == false) { //error @@ -218,7 +220,6 @@ while (hexString.length < size) { return {type: 'ERROR', value: null}; }else{ //return the address - console.log(labelobj) return {type: 'NUMBER', value: labelobj.address} }}, @@ -227,7 +228,6 @@ while (hexString.length < size) { confirmationfunction : (input) => { var errormsg = [] var err = false ; - //console.log(input) // check Errorcalm.SemanticError first else do the thing you where doing if (Errorcalm.SemanticError.length > 0) { Errorcalm.printError(); @@ -247,7 +247,6 @@ while (hexString.length < size) { addrmod : (listofpar,line) => { - console.log(listofpar); // go through the list of instructions if listofpar[index].value is different then , then add this element.value to the list 1 // go throught an if there is an element.type='TEXT' you use Labeltonum to make it a number listofpar.forEach((element,index) => { @@ -442,13 +441,9 @@ export class Assembler{ Errorcalm.printError(); }else{ this.input = lexicalList; - console.log("\nLexicalList:\n",lexicalList) this.toAssemble = new SemanticAnalysis(this.input); let ret = FuncInterface.confirmationfunction(this.toAssemble.Semanticlist); - if (!ret.status) { - console.log("\nThere are errors in your code cannot assemble:\n"); - console.log(ret.errors); - }} + } } static assemble(input){ @@ -518,22 +513,16 @@ export class Assembler{ ind = '00'; regmod1 = FuncInterface.regmap(input[1].value); regmod2 = FuncInterface.regmap(input[2].value); - code = opcode + ind + regmod1 + regmod2 - - //return {codehex:FuncInterface.binaryToHex(code,code.length/4),codebin:code}; return FuncInterface.binaryToHex(code,code.length/4) - - break; - + break; break; case 'REGISTER,NUMBER': ind = '01'; regmod1 = FuncInterface.regmap(input[1].value); regmod2 = FuncInterface.adrmap(input[2].adrmode,size, typeof input[2].depl =='undefined' ? 0 : input[2].depl>255 ? '1' :'0' ); - //console.log(regmod2) - + //console.log(regmod2) switch (regmod2) { case '000': let long = size == 0 ? 8 : 16; @@ -633,7 +622,6 @@ export class Assembler{ case '111': dep1 = FuncInterface.decimalTobinByte(input[1].depl, input[1].depl > 255 ? 16 : 8 ); op1 = FuncInterface.decimalTobinByte(input[1].value,16); - console.log("dep1 here",FuncInterface.binaryToHex(dep1,4)) break; case '011': case '100': @@ -660,13 +648,11 @@ export class Assembler{ case '110': dep2 = FuncInterface.decimalTobinByte(input[2].depl, input[2].depl > 255 ? 16 : 8 ); op2 = FuncInterface.decimalTobinByte(input[2].value,16); - console.log("dep2 here size 0-----------",dep2) break; case '111': dep2 = FuncInterface.decimalTobinByte(input[2].depl , input[2].depl > 255 ? 16 : 8 ); op2 = FuncInterface.decimalTobinByte(input[2].value, 16 ); - console.log("dep2 here size 2",FuncInterface.binaryToHex(dep2,4)) case '011': case '100': @@ -690,9 +676,7 @@ export class Assembler{ //console.log(dep1) //console.log(FuncInterface.binaryToHex(dep1,4)) //console.log(FuncInterface.binaryToHex(code,code.length/4)) - console.log("code here",code) - console.log("code here",FuncInterface.binaryToHex(code,code.length/4)) - return FuncInterface.binaryToHex(code,code.length/4) + return FuncInterface.binaryToHex(code,code.length/4) break; default: @@ -861,28 +845,44 @@ export class Assembler{ break; } let instcode=oppcode+adr; - return instcode; - + return instcode; } - } - - } static assemblecode(input){ let output = new Assembler(input) ; var assembledcode = []; var toassmb = (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"; - console.log("\nSemantic list: \n",toassmb) - if ( Errorcalm.SemanticError.length ===0 ) { - + var ipTrack = 0; + var i=0; + var lines=(Assembler.Labellist.length === 0 )?toassmb.length:Assembler.Labellist[i].linedeclared; + console.log("lines: ",lines) + // deux pass first pass stays as it is with adding a delimater at each label and then re apply the semantic analysis for the labels and then reassemble the code + if ( Errorcalm.SemanticError.length === 0 ) { for (let index = 0; index < toassmb.length; index++) { - - assembledcode.push(Assembler.assemble(toassmb[index])) - + console.log("index: ",index) + console.log("lines: ",lines) + if (index >= lines) { + Assembler.Labellist[i].address = ipTrack + console.log("check labellist: ",Assembler.Labellist); + i++; + if (i < Assembler.Labellist.length) { + lines=Assembler.Labellist[i].linedeclared-Assembler.Labellist[i-1].linedeclared-1+index; + }else{ + lines=toassmb.length; + } + } + ipTrack = ipTrack+(Assembler.assemble(toassmb[index]).length/2) } - console.log("\nAssembled code: \n",assembledcode) - return assembledcode; + SemanticAnalysis.labeltype = false; + output = new Assembler(input) + toassmb = (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"; + console.log("to assumb status: ",toassmb) + for (let index = 0; index < toassmb.length; index++) { + assembledcode.push(Assembler.assemble(toassmb[index])) + } + console.log(assembledcode); + return assembledcode; // here put the return in case of success }else{ @@ -898,8 +898,6 @@ export class Assembler{ - console.log("\nLabel list: \n",Assembler.Labellist) - //var input = ["MOV 0,0"] //console.log("\nInput: \n", Assembler.assemblecode(input)) diff --git a/src/assembler/Errorcalm.js b/src/assembler/Errorcalm.js index b834f85..a71e66c 100644 --- a/src/assembler/Errorcalm.js +++ b/src/assembler/Errorcalm.js @@ -42,7 +42,6 @@ export class Errorcalm{ numerr ==1 ? theError="\nThere is 1 error in your code:\n" : theError=`\nThere are ${numerr} errors in your code cannot assemble:\n`; Errorcalm.LexicalError.length == 0 ? theError+=" Semantic Errors:\n"+" "+Errorcalm.SemanticError[0].message+"\n the line : "+Errorcalm.SemanticError[0].linenum : theError+="Lexical Errors \n"+" "+Errorcalm.LexicalError[0].message+"\n the line :"+Errorcalm.LexicalError[0].line; Errorcalm.errorr=1; - console.log(this.SemanticError); return theError;} } static addtoSemanticError(errs){ diff --git a/src/assembler/Lexer.js b/src/assembler/Lexer.js index 49ac01d..632ccad 100644 --- a/src/assembler/Lexer.js +++ b/src/assembler/Lexer.js @@ -1,3 +1,6 @@ +/* eslint-disable eqeqeq */ +/* eslint-disable no-useless-escape */ +/* eslint-disable no-unused-vars */ import { Assembler } from './Assembler.js'; import { Errorcalm } from './Errorcalm.js'; import { SemanticAnalysis } from './SemanticAnalysis.js'; @@ -113,7 +116,7 @@ export class Lexer { return [ { type: 'LABEL' }, - { type: 'TEXT', value: labelText }, + { type: 'TEXTT', value: labelText }, { type: 'NUMBER', value: line.toString() } ]; } @@ -132,7 +135,6 @@ export class Lexer { }]; } }); - // Flatten the array of arrays into a single array let lexlist = this.LexicalList.flat(); lexlist.forEach((element, index, lexlist) => { diff --git a/src/assembler/SemanticAnalysis.js b/src/assembler/SemanticAnalysis.js index 29c8799..e2c2e5d 100644 --- a/src/assembler/SemanticAnalysis.js +++ b/src/assembler/SemanticAnalysis.js @@ -1,3 +1,5 @@ +/* eslint-disable default-case */ +/* eslint-disable no-loop-func */ import { Lexer } from './Lexer.js'; import { Errorcalm } from './Errorcalm.js'; import { Assembler,FuncInterface } from "./Assembler.js"; @@ -5,40 +7,47 @@ import { Assembler,FuncInterface } from "./Assembler.js"; export class SemanticAnalysis { Semanticlist = [] - + static labeltype = true; constructor(input) { let lexicalList = input; for(let i = 0; i < lexicalList.length; i++){ - let firstword = lexicalList[i][0] let firstwordtype = firstword.type if (firstwordtype == 'LABEL') { if (lexicalList[i].length == 3) { if (lexicalList[i][2].type == 'NUMBER') { if( lexicalList[i][2].value < Assembler.MAXNUM){ - if(lexicalList[i][1].type == 'TEXT'){ + if(lexicalList[i][1].type == 'TEXT' ||lexicalList[i][1].type == 'TEXTT'){ if(Lexer.isValidString(lexicalList[i][1].value)){ // filters for text standards and validity of the text // check if label already existing var found = false ; var labelname = lexicalList[i][1].value ; Assembler.Labellist.forEach(element => { - if(element.name === labelname){ + if((element.name === labelname) && (SemanticAnalysis.labeltype === element.label)){ + console.log(element.name + " " + labelname + " " + SemanticAnalysis.labeltype + " " + element.label) found = true } }); - if (!found) { - //this.Semanticlist.push(lexicalList[i]); - //stop pushing here because we don't need it - Assembler.Labellist.push({ name: labelname, address: lexicalList[i][2].value, linedeclared:i }) + if (!found) { + if (lexicalList[i][1].type === 'TEXTT') { + if (SemanticAnalysis.labeltype){ + Assembler.Labellist.push({ name: labelname, address: lexicalList[i][2].value, linedeclared:i, label: true }) + } + } + else { + if (!SemanticAnalysis.labeltype){ + Assembler.Labellist.push({ name: labelname, address: lexicalList[i][2].value, linedeclared:i, label: false }) + } + } }else{ - this.Semanticlist.push(new Errorcalm("LABEL already declared",null,i)) + this.Semanticlist.push(new Errorcalm("LABEL already declared",null,i)) } }else{ this.Semanticlist.push(new Errorcalm("LABEL name is not valid",null,i)) } - }else{ - this.Semanticlist.push(new Errorcalm("LABEL name not defined",null,i)) - } + }else{ + this.Semanticlist.push(new Errorcalm("LABEL name not defined",null,i)) + } }else{ this.Semanticlist.push(new Errorcalm("Number size is bigger then MAXNUM",null,i)) } diff --git a/src/components/AdressingModeListing/index.jsx b/src/components/AdressingModeListing/index.jsx index af31173..9887747 100644 --- a/src/components/AdressingModeListing/index.jsx +++ b/src/components/AdressingModeListing/index.jsx @@ -4,7 +4,6 @@ import "./style.css" const AdressingModeListing = ({name, imagePath, open}) => { - console.log(imagePath); return ( <> { const handleSubmit = (e) => { //prevent the form from reloading the page e.preventDefault(); - console.log(document.querySelector('.auth-button').disabled); document.querySelector('.auth-button').disabled = true; //get the form error div const formError = document.getElementById('form-error') @@ -37,8 +36,7 @@ const AuthForm = ({currentRoute, redirectRoute, updateCurrentUser}) => { navitage('/check-email'); return; } - console.log(user) - + if(currentRoute === '/login' && !user.confirmed){ formError.innerText = "Confirm your email first!" return; @@ -55,7 +53,6 @@ const AuthForm = ({currentRoute, redirectRoute, updateCurrentUser}) => { }) .catch(err => { //show the error in the front - console.log(err) if(!err.response.data.message){ formError.innerText = "Unknown Server error"; } diff --git a/src/components/ComponentsListing/index.jsx b/src/components/ComponentsListing/index.jsx index f4d4853..d650e1a 100644 --- a/src/components/ComponentsListing/index.jsx +++ b/src/components/ComponentsListing/index.jsx @@ -2,8 +2,7 @@ import React from "react"; import {motion} from "framer-motion"; import "./style.css" const ComponentsListing = ({ name, imagepath, imageHeight, open }) => { - console.log(imagepath) - + return ( <> { - console.log("program",program) const navigate = useNavigate(); const handleDeleteProgram = (e) => { @@ -16,11 +15,9 @@ const ProgramContainer = ({userId, program, removeProgram}) => { axios.delete(URL) .then(response => { - console.log(response); - removeProgram(program); + removeProgram(program); }) .catch(err => { - console.log(err); alert("Failed to delete program!") }) } diff --git a/src/components/SaveCodeButton/index.jsx b/src/components/SaveCodeButton/index.jsx index d788bf8..f72af60 100644 --- a/src/components/SaveCodeButton/index.jsx +++ b/src/components/SaveCodeButton/index.jsx @@ -13,19 +13,16 @@ const SaveCodeButton = ({code, currentUser, editMode}) => { return; } - console.log("Saving your code..."); - // console.log(code) isEditMode + // console.log(code) isEditMode const URL = process.env.REACT_APP_API_URL+`/user/${currentUser.id}/code` + (editMode.isEditMode === true ? "/edit" : "/add") if(editMode.isEditMode === true){ axios.put(URL, {id: editMode.programId,code}) .then(res => { - console.log(res); alert(`Program "${editMode.programName}" updated successfully`); }) .catch(err => { - console.log(err); alert("Program update failed!"); }) }else{ @@ -38,11 +35,9 @@ const SaveCodeButton = ({code, currentUser, editMode}) => { axios.post(URL, {code, name: programName}) .then(res => { - console.log(res) alert("Your code has been saved successfully!") }) .catch(err => { - console.log(err); alert("Program save failed!"); }) } diff --git a/src/pages/Ide/index.jsx b/src/pages/Ide/index.jsx index 70cf5ce..cdd9857 100644 --- a/src/pages/Ide/index.jsx +++ b/src/pages/Ide/index.jsx @@ -91,6 +91,7 @@ const Ide = ({currentUser})=>{ } memory.setcode(codeArray) + console.log("long waited memory code is here:\n\n"+memory.code) queue.instructionset([]); let numtmp=0; From cf45b63fc1b54f415fc052f2b74f3225892c04e9 Mon Sep 17 00:00:00 2001 From: Louaighoul Date: Sat, 15 Mar 2025 12:41:37 +0000 Subject: [PATCH 04/12] I/O ADDED --- src/Emulator.zip | Bin 0 -> 27555 bytes src/Emulator/IO_Unit.js | 41 ++++- src/Emulator/Instruction.js | 218 ++++++++++++++++++++++++- src/Emulator/MC.js | 85 ++++++---- src/Emulator/Opcodes.js | 19 ++- src/Emulator/Queue.js | 2 +- src/Emulator/Sequencer.js | 2 +- src/codemirror/mode/myLang/assembly.js | 88 +++++----- src/pages/Ide/index.jsx | 19 ++- 9 files changed, 378 insertions(+), 96 deletions(-) create mode 100644 src/Emulator.zip diff --git a/src/Emulator.zip b/src/Emulator.zip new file mode 100644 index 0000000000000000000000000000000000000000..82d84a1a1553f9ddb507f8127959962b7910b0de GIT binary patch literal 27555 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 y8Q?Eib@@NA|7k|@-;n>TE`Ke new generalPurposeRegister()); + + // I/O Controller: Manages data transfer and communication + this.ioController = { + busy: false, // Indicates if an I/O operation is in progress + sequencerSignal: null, // Signal from sequencer + ioInterfaceSignal: null // Signal from I/O interface + }; } - getBuffer() { - return this.buffer; + writeToBuffer(registerIndex, value) { + if (registerIndex < 0 || registerIndex >= 4) { + throw new Error("Invalid register index"); + } + this.buffer[registerIndex].setvalue(value); + this.ioController.busy = true; } - setBuffer(buffer) { - this.buffer = buffer; + + + readFromBuffer(registerIndex) { + if (registerIndex < 0 || registerIndex >= 4) { + throw new Error("Invalid register index"); + } + return this.buffer[registerIndex].getvalue(); } - write() { - console.log(this.buffer); + displayValue() { + console.log("I/O Buffer Contents:"); + this.buffer.forEach((reg, index) => { + console.log(`Register ${index}: ${reg.getvalue()}`); + }); } } -export default IOUnit; \ No newline at end of file + +export default IOUnit; diff --git a/src/Emulator/Instruction.js b/src/Emulator/Instruction.js index 407819b..ca93993 100644 --- a/src/Emulator/Instruction.js +++ b/src/Emulator/Instruction.js @@ -1,11 +1,74 @@ -import { Registers, memory, Alu1, IP ,queue } from "../pages/Ide"; +import { Registers, memory, Alu1, IP ,queue } from "../pages/Ide/index.jsx"; import { TwosComplement } from "./ALU.js"; import { gsap } from "gsap"; +import IOUnit from "./IO_Unit.js"; +import { Register } from "./Register.js"; // import { Register } from "./Register.js"; //////////////////////////////////////////////// function Dec2bin(dec){ return ("00000000" + (parseInt(dec, 10)).toString(2)).substr(-8); } +function binaryToDecimalNumber(binaryStr) { + return parseInt(binaryStr, 2); +} +// Ensure receiveWriteValue is globally accessible +// Ensure receiveWriteValue is globally accessible +function showWritePopup() { + return new Promise((resolve) => { + let popup = window.open("", "Write to Register", "width=400,height=300"); + + popup.document.write(` +

Write to Register

+ + + + + + `); + + // Store resolve function globally so it can return the value to the main window + window.resolveWriteValue = (value) => { + console.log("🟢 Received input from user:", value); + resolve(parseInt(value, 10) || 0); // Convert input to number (default 0 if empty) + }; + }); +} + + + + +window.receiveWriteValue = function(value) { + console.log("✅ Main Window: Received value from pop-up:", value); + + const ioUnit = memory.ioUnit; + + if (!isNaN(value)) { + value = parseInt(value, 10); + ioUnit.writeToBuffer(0, value); + console.log(`✅ Stored ${value} in I/O buffer register 0.`); + + // Resume instruction execution + if (typeof window.writeCallback === "function") { + console.log("🟢 Resuming instruction after user input..."); + window.writeCallback(); + window.writeCallback = null; // Clear the callback after execution + } + } else { + console.log("❌ Invalid input. Please enter a number."); + } +}; + + /////////////////animations to test//////////////////// const IounitToBus={ @@ -18,6 +81,22 @@ const IounitToBus={ gsap.to(".ball",{opacity:"0" ,duration:1,delay:2}); }, } +const BusToIO = { + value: "", + target: ".ball", + time: 3000, + anim: (val, h, w) => { + gsap.fromTo(".ball", + { height: "2.812%", width: "1.4%", borderRadius: "50%", x: w * 0.221, y: h * 0.46, opacity: "0" }, + { opacity: "1", duration: 1 } + ); + gsap.fromTo(".ball", + { x: w * 0.221, y: h * 0.46 }, + { y: h * 0.39, duration: 1, delay: 1 } // Moves upward, opposite of IOTOBUS + ); + gsap.to(".ball", { opacity: "0", duration: 1, delay: 2 }); + }, +}; const BusToRual1={ value:"", @@ -4359,5 +4438,140 @@ class InstructionPOPA{ this.buildanim=function(){} } } +class InstructionREAD { + constructor() { + this.value1 = 0; + this.value2 = 0; + this.addresse1 = 0; + this.register1 = 0; + this.addresse2 = 0; + this.register2 = 0; + this.taille = 0; + this.stepsNum = 1; + this.name = "READ"; + + this.steps = [ + () => { + const ioUnit = memory.ioUnit; // Access I/O Unit + + if (!ioUnit.ioController.busy) { + ioUnit.ioController.busy = true; // Mark I/O as busy + + let value = this.value1; // Read from CPU register (e.g., R1) + ioUnit.writeToBuffer(0, value); + let popup = window.open("", "Buffer Contents", "width=400,height=300"); + popup.document.write(`

Buffer Contents

${ioUnit.readFromBuffer(0)}

`); + // alert("Buffer Contents: " + ioUnit.readFromBuffer(0));// Store in I/O buffer register 0 + + console.log(`CPU to IO: Moved data ${value} from CPU register R${this.register1} to I/O buffer.`); + ioUnit.displayValue(); + ioUnit.ioController.busy = false; + } else { + console.log("I/O Unit busy, READ delayed"); + return false; // Delay execution if busy + } + }, + ]; + this.buildanim = function () { + return [ + { + value: "READ", + target: addanim.target, + time: addanim.time, + anim: addanim.anim, + }, + { + value: this.value1, + target: RegistersToBus.target, + time: RegistersToBus.time, + anim: RegistersToBus.anim, + }, + { + value: this.value1, + target: BusToIO.target, + time: BusToIO.time, + anim: BusToIO.anim, + }, + + + ]; + }; + } +} + +class InstructionWRITE { + constructor() { + this.value1 = 0; + this.value2 = 0; + this.addresse1 = 0; + this.register1 = 0; + this.addresse2 = 0; + this.register2 = 0; + this.taille = 0; + this.stepsNum = 1; + this.name = "WRITE"; + + this.steps = [ + async () => { + const ioUnit = memory.ioUnit; + + if (!ioUnit.ioController.busy) { + ioUnit.ioController.busy = true; + + console.log("🟢 InstructionWRITE: Waiting for user input..."); + + // Wait for user input asynchronously before proceeding + const value = await showWritePopup(); + + ioUnit.writeToBuffer(0, value); + console.log(`✅ User input received: ${value}. Stored in I/O buffer register 0.`); + + // Resume execution + this.resume(); + } else { + console.log("🔴 InstructionWRITE: I/O Unit busy, WRITE delayed"); + return false; + } + } + ]; + + // Animation sequence + this.buildanim = function () { + const ioUnit = memory.ioUnit; + return [ + { + value: "WRITE", + target: addanim.target, + time: addanim.time, + anim: addanim.anim, + }, + { + value: ioUnit.readFromBuffer(0), + target: IounitToBus.target, + time: IounitToBus.time, + anim: IounitToBus.anim, + }, + { + value: ioUnit.readFromBuffer(0), + target: BusToRegisters.target, + time: BusToRegisters.time, + anim: BusToRegisters.anim, + }, + ]; + }; + } + + resume() { + const ioUnit = memory.ioUnit; + + let value = ioUnit.readFromBuffer(0); + let register = parseInt(this.register1, 2); + Registers[register].setvalue(TwosComplement(value, 16)); + + ioUnit.ioController.busy = false; + console.log(`✅ IO to CPU: Moved data ${value} from I/O buffer to CPU register R${register}.`); + } +} + -export {InstructionADD,InstructionMOV00,InstructionMOV01,InstructionMOV10,InstructionMOV11,InstructionSUB,InstructionMUL,InstructionDIV,InstructionBSE,InstructionBIE,InstructionBI,InstructionBS,InstructionBNE,InstructionBE,InstructionBR,InstructionPOP,InstructionPUSH,InstructionAND,InstructionOR,InstructionNAND,InstructionNOR,InstructionXOR,InstructionNEG,InstructionNOT,InstructionROL,InstructionROR,InstructionSHL,InstructionSHR,InstructionPOPA,InstructionPUSHA} +export {InstructionADD,InstructionMOV00,InstructionMOV01,InstructionMOV10,InstructionMOV11,InstructionSUB,InstructionMUL,InstructionDIV,InstructionBSE,InstructionBIE,InstructionBI,InstructionBS,InstructionBNE,InstructionBE,InstructionBR,InstructionPOP,InstructionPUSH,InstructionAND,InstructionOR,InstructionNAND,InstructionNOR,InstructionXOR,InstructionNEG,InstructionNOT,InstructionROL,InstructionROR,InstructionSHL,InstructionSHR,InstructionPOPA,InstructionPUSHA,InstructionREAD, InstructionWRITE} \ No newline at end of file diff --git a/src/Emulator/MC.js b/src/Emulator/MC.js index 46b1c8b..e08a680 100644 --- a/src/Emulator/MC.js +++ b/src/Emulator/MC.js @@ -1,49 +1,68 @@ -import { Register } from "./Register.js" +import { Register } from "./Register.js"; +import IOUnit from "./IO_Unit.js"; // 🔥 Import IOUnit + class MC { - constructor(){ - this.rim=new Register() - this.ram=new Register() - this.stack = new Array(100)//size à revoir - this.data = new Array (100) - this.code = new Array(100) + constructor() { + this.rim = new Register(); + this.ram = new Register(); + this.mar = new Register(); + this.stack = new Array(100); // size à revoir + this.data = new Array(100); + this.code = new Array(100); + this.ioUnit = new IOUnit(); // ✅ Add IOUnit instance } - setcode(code){ - this.code=code; + + setcode(code) { + this.code = code; } - setRim (val){//val in hexa - this.rim=val; + + setRim(val) { // val in hexa + this.rim = val; } - setRam (adr){//val in decimal - this.ram=adr; + + setRam(adr) { // val in decimal + this.ram = adr; } - getRam(){ - return this.ram; + + getRam() { + return this.ram; } - getRim (){ - return this.rim + + getRim() { + return this.rim; } - read(iscode){ - if(iscode==true){ - this.rim=this.code[parseInt(this.ram,2)] + + read(iscode) { + if (iscode == true) { + this.rim = this.code[parseInt(this.ram, 2)]; + } else { + this.rim = this.data[parseInt(this.ram, 2)]; + } } - else{ - this.rim=this.data[parseInt(this.ram,2)] + + write() { + this.data[parseInt(this.ram, 2)] = this.rim; } + + popval() { + this.rim = this.stack.pop(); } - write(){ - this.data[parseInt(this.ram,2)]=this.rim; + + pushval() { + this.stack.push(this.rim); } - popval(){ - this.rim=this.stack.pop(); - } - pushval(){ - this.stack.push(this.rim); - } - getData(){ + + getData() { return this.data; } - getstack(){ + + getstack() { return this.stack; } + + getIOUnit() { // ✅ Helper method to get IOUnit + return this.ioUnit; + } } -export default MC; \ No newline at end of file + +export default MC; diff --git a/src/Emulator/Opcodes.js b/src/Emulator/Opcodes.js index 0227590..0a08928 100644 --- a/src/Emulator/Opcodes.js +++ b/src/Emulator/Opcodes.js @@ -1,4 +1,4 @@ -import { InstructionADD,InstructionMOV00,InstructionMOV01,InstructionMOV10,InstructionMOV11,InstructionSUB,InstructionMUL,InstructionDIV, InstructionPUSH, InstructionBR, InstructionNOR, InstructionNEG, InstructionROR, InstructionROL, InstructionSHL, InstructionSHR, InstructionBE, InstructionBS, InstructionBSE, InstructionBI, InstructionBIE, InstructionBNE, InstructionNOT, InstructionOR, InstructionAND, InstructionNAND, InstructionXOR } from "./Instruction.js"; +import { InstructionADD,InstructionMOV00,InstructionMOV01,InstructionMOV10,InstructionMOV11,InstructionSUB,InstructionMUL,InstructionDIV, InstructionPUSH, InstructionBR, InstructionNOR, InstructionNEG, InstructionROR, InstructionROL, InstructionSHL, InstructionSHR, InstructionBE, InstructionBS, InstructionBSE, InstructionBI, InstructionBIE, InstructionBNE, InstructionNOT, InstructionOR, InstructionAND, InstructionNAND, InstructionXOR, InstructionREAD, InstructionWRITE } from "./Instruction.js"; function hash(key){ if(key=="0000000"){ @@ -55,7 +55,12 @@ function hash(key){ return 25; }else if(key=="0000110"){//XOR return 26; + } else if(key=="1000"){ // Opcode for READ + return 27; + } else if(key=="1001"){ // Opcode for WRITE + return 28; } + } let ADDinst=new InstructionADD(); let MOV00inst=new InstructionMOV00(); @@ -84,6 +89,8 @@ let ORinst = new InstructionOR(); let ANDinst = new InstructionAND(); let NANDinst = new InstructionNAND(); let XORinst = new InstructionXOR(); +let READinst = new InstructionREAD(); +let WRITEinst = new InstructionWRITE(); let hashmap=[{ key:"00", instrObject:ADDinst, @@ -192,5 +199,13 @@ let hashmap=[{ key:"0c", instrObject:XORinst, }, +{ + key:"8", + instrObject:READinst +}, +{ + key:"9", + instrObject:WRITEinst +} ]; -export {hash,hashmap}; \ No newline at end of file +export {hash,hashmap}; diff --git a/src/Emulator/Queue.js b/src/Emulator/Queue.js index 6b3db03..c965c14 100644 --- a/src/Emulator/Queue.js +++ b/src/Emulator/Queue.js @@ -1,4 +1,4 @@ -import { memory,IP } from "../pages/Ide"; +import { memory,IP } from "../pages/Ide/index.jsx"; import { TwosComplement } from "./ALU.js"; import { gsap } from "gsap"; diff --git a/src/Emulator/Sequencer.js b/src/Emulator/Sequencer.js index 1b56151..be050f9 100644 --- a/src/Emulator/Sequencer.js +++ b/src/Emulator/Sequencer.js @@ -1,5 +1,5 @@ import { Register } from "./Register.js"; -import { queue, Registers, addressingModes } from "../pages/Ide"; +import { queue, Registers, addressingModes } from "../pages/Ide/index.jsx"; import { hash, hashmap } from "./Opcodes.js"; import { gsap } from "gsap"; // import Console from "../Console.jsx";____conflict!!!!!!!!!! diff --git a/src/codemirror/mode/myLang/assembly.js b/src/codemirror/mode/myLang/assembly.js index 526754e..6b30980 100644 --- a/src/codemirror/mode/myLang/assembly.js +++ b/src/codemirror/mode/myLang/assembly.js @@ -1,5 +1,5 @@ import define from 'requirejs' -import CodeMirror from 'codemirror' +import CodeMirror from 'codemirror' (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -14,11 +14,18 @@ import CodeMirror from 'codemirror' })(function(CodeMirror) { CodeMirror.defineMode("8086", function(config, parserConfig) { - var keywords = ["mov", "add", "sub", "mul", "div", "jmp", "call", "ret", "push", "pop", "label", "bri", "be", "bne", "bs", "bi", "bse", "bie", "ror", "rol", "shr", "shl"]; - var registers = ["r1", "r2", "r3", "r4", "idr", "br", "sr", "acc", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h", "accl", "acch"]; + var keywords = ["mov", "add", "sub", "mul", "div", "jmp", "call", "ret", "push", "pop", + "label", "bri", "be", "bne", "bs", "bi", "bse", "bie", "ror", "rol", + "shr", "shl", "read", "write"]; // Added "read" and "write" + + var registers = ["r1", "r2", "r3", "r4", "idr", "br", "sr", "acc", "r1l", "r1h", "r2l", + "r2h", "r3l", "r3h", "accl", "acch"]; + var number = /-?(?:0x[0-9a-f]+|\d+)/i; + function tokenBase(stream, state) { var ch = stream.next(); + if (ch === "/") { if (stream.eat("")) { state.tokenize = tokenComment; @@ -29,69 +36,68 @@ import CodeMirror from 'codemirror' return "comment"; } } + if (ch === ";" || ch === "#") { stream.skipToEnd(); return "comment"; } + if (/[a-zA-Z_]/.test(ch)) { stream.eatWhile(/[\w.]/); var cur = stream.current().toLowerCase(); - if (keywords.indexOf(cur) >= 0) { - return "key"; - } - if (registers.indexOf(cur) >= 0) { - return "reg"; - } - + if (keywords.indexOf(cur) >= 0) { + return "key"; // READ & WRITE will now be highlighted as instructions + } + if (registers.indexOf(cur) >= 0) { + return "reg"; } - if (/\d/.test(ch)) { + } + + if (/\d/.test(ch)) { stream.match(number); return "num"; - } + } if(/[@*]/.test(ch)){ return "opadr"; } if(/[[]]/.test(ch)){ - return "opadr" + return "opadr"; } + return null; + } - return null; - } - - function tokenComment(stream, state) { - let maybeEnd = false, ch; + function tokenComment(stream, state) { + let maybeEnd = false, ch; - while ((ch = stream.next())) { - if (ch === "/" && maybeEnd) { - state.tokenize = null; - break; + while ((ch = stream.next())) { + if (ch === "/" && maybeEnd) { + state.tokenize = null; + break; + } + maybeEnd = ch === ""; } - maybeEnd = ch === ""; + return "comment"; } - return "comment"; - } - - return { - startState: function() { - return { - tokenize: null, - }; - }, + return { + startState: function() { + return { + tokenize: null, + }; + }, - token: function(stream, state) { - if (state.tokenize) { - return state.tokenize(stream, state); - } - - return tokenBase(stream, state); - }, - }; + token: function(stream, state) { + if (state.tokenize) { + return state.tokenize(stream, state); + } + return tokenBase(stream, state); + }, + }; }); -}); \ No newline at end of file +}); diff --git a/src/pages/Ide/index.jsx b/src/pages/Ide/index.jsx index e18c69d..de92464 100644 --- a/src/pages/Ide/index.jsx +++ b/src/pages/Ide/index.jsx @@ -5,7 +5,7 @@ import UAParser from 'ua-parser-js'; import "./style.css" ///// import components ////// -import { NavBar, HelpSection, SaveCodeButton } from "../../components" +import { NavBar, HelpSection, SaveCodeButton } from "../../components/index.js" ////// import machine components ////// @@ -24,10 +24,10 @@ import "../../codemirror/theme/material.css"; import "../../codemirror/mode/myLang/assembly.js" /////import assembler modules////////// -import { Assembler } from "../../assembler/Assembler"; -import {helpDescription} from "../../Constants/HelpDescription"; -import {HexaToCode} from "../../HexaToCode/HexaToCode" -import { Errorcalm } from "../../assembler/Errorcalm"; +import { Assembler } from "../../assembler/Assembler.js"; +import {helpDescription} from "../../Constants/HelpDescription.js"; +import {HexaToCode} from "../../HexaToCode/HexaToCode.js" +import { Errorcalm } from "../../assembler/Errorcalm.js"; import { useLocation } from 'react-router-dom'; import { useEffect } from 'react'; @@ -336,20 +336,25 @@ const Ide = ({currentUser})=>{ if(iscode){ inputouter=Assembler.assemblecode(handleStoreCode()) + }else{ inputouter=handleStoreCode(); } let input=convertStrings(inputouter); input.push("ff"); + console.log("this is :"+ input) try { - + console.log("hachmi"); if (Errorcalm.errorr === 0) { + console.log("drsas") traitement(input); - + }else{ + console.log("SIks") setresult(Errorcalm.printError()); + seterr(true); } From b357d550e4bfdbb4d053325a297cfda408b045e9 Mon Sep 17 00:00:00 2001 From: redouane-bensaci Date: Sat, 15 Mar 2025 14:01:51 +0100 Subject: [PATCH 05/12] test --- src/assembler/Assembler.js | 5 +++++ src/assembler/preprocessing.js | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/assembler/Assembler.js b/src/assembler/Assembler.js index 585d2a5..a56cdae 100644 --- a/src/assembler/Assembler.js +++ b/src/assembler/Assembler.js @@ -850,9 +850,13 @@ export class Assembler{ } } static assemblecode(input){ + SemanticAnalysis.labeltype = true; + console.log("input: ",input) let output = new Assembler(input) ; + console.log("output: ",output) var assembledcode = []; var toassmb = (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"; + console.log("to assumb status: ",toassmb) var ipTrack = 0; var i=0; var lines=(Assembler.Labellist.length === 0 )?toassmb.length:Assembler.Labellist[i].linedeclared; @@ -872,6 +876,7 @@ export class Assembler{ lines=toassmb.length; } } + console.log("check labellist: ",Assembler.Labellist); ipTrack = ipTrack+(Assembler.assemble(toassmb[index]).length/2) } SemanticAnalysis.labeltype = false; diff --git a/src/assembler/preprocessing.js b/src/assembler/preprocessing.js index 9f34c97..4c085d2 100644 --- a/src/assembler/preprocessing.js +++ b/src/assembler/preprocessing.js @@ -1,3 +1,4 @@ +/* eslint-disable import/no-anonymous-default-export */ class preprocessing{ static keyWords = ['MACRO', 'ENDM', 'START', 'END'] @@ -189,4 +190,4 @@ class preprocessing{ } -module.exports = { preprocessing } \ No newline at end of file +export default { preprocessing } \ No newline at end of file From 68e5fc993577d1ef76da21f6a9567b16bc0dab6c Mon Sep 17 00:00:00 2001 From: nejem Eddine Mekentichi <83135662+Nejmeddine-Mek@users.noreply.github.com> Date: Mon, 17 Mar 2025 22:36:05 +0100 Subject: [PATCH 06/12] added basic functionality for data segment, remains to handle any unhandled errors and reshape the return format for upcoming steps if needed --- src/assembler/preprocessing.js | 221 +++++++++++++++++++++++++++++++-- 1 file changed, 208 insertions(+), 13 deletions(-) diff --git a/src/assembler/preprocessing.js b/src/assembler/preprocessing.js index 4c085d2..167081e 100644 --- a/src/assembler/preprocessing.js +++ b/src/assembler/preprocessing.js @@ -1,19 +1,26 @@ -/* eslint-disable import/no-anonymous-default-export */ +const ErrorCalm = require("./assembler/Errorcalm.js") class preprocessing{ - static keyWords = ['MACRO', 'ENDM', 'START', 'END'] + //this should include all reserved words, or if there is a global object serving the same purpose + static reservedWords = new Set(['R1', 'R2', 'R3', 'R4', 'ACC', 'BR', 'IDR', 'SR', 'R1R', 'R2R', 'R3R', 'ACCR', 'R1L', 'R2L', 'R3L', 'ACCL' + , 'PUSHA', 'POPA', 'RET', 'NEG', 'NOT', 'SHL', 'SHR', 'READ', 'WRITE', 'PUSH', 'POP', 'ROR', 'ROL', 'CALL', 'BE', 'BNE', 'BS', 'BI', 'BIE', 'BSE', 'BRI' + , 'NAND', 'CMP', 'MOV', 'ADD', 'SUB', 'MUL', 'DIV', 'AND', 'OR', 'XOR', 'NOR', 'MACRO', 'ENDM', 'START', 'END','SDATA', 'ENDS']) + static macroKeyWords = ['MACRO', 'ENDM'] static DataKeyword = ['SDATA', 'ENDS'] constructor(){ this.MACROS = [] this.macroKeyWord = new Set() this.labelSymbolList = [] this.dataSegment = [] + this.errors = [] + this.varList = [] + this.data = [] } getDataSegment(code){ const n = code.length - for(let i = 0; i < n ; i++){ - + let i = 0 + while( i < n && code[i] !== 'START'){ if(code[i] === 'SDATA'){ i += 1 let endOfSeg = false @@ -24,17 +31,113 @@ class preprocessing{ } if(i === n){ //error segment not closed + this.errors.push(new ErrorCalm("Data segment not closed", "PREPROCESSING", i)) return } this.dataSegment.push(code[i++]) } break } + i += 1 } console.log('data: ', this.dataSegment) } + + // allocate space in memory, to get addresses of variables + allocateData(){ + if(this.dataSegment.length === 0){ + // no data segment, no need to allocate + console.log("no data") + return + } + // here, we first should decide whether we compact the memory or not, so we either work from 0 or from the end of stack segment at @ = 256 + let curAddress = 0 + let n = this.dataSegment.length + for(let i = 0; i < n; i++){ + let line = this.dataSegment[i].split(' ') + // we want to get an array in this form [label, length, value(s)] + // for example [X, db, 15] + if(line.length < 3){ + // throw error, wrong variable declaration + this.errors.push(new ErrorCalm("Wrong variable declaration", "PREPROCESSING", i)) + return + } + if(this.varList.includes(line[0])){ + // throw error, variable already declared + this.errors.push(new ErrorCalm("Variable already declared", "PREPROCESSING", i)) + return + } + if(!isNaN(Number(line[0][0]))){ + // throw error, variable name cannot start with a number + this.errors.push(new ErrorCalm("Variable name cannot start with a number", "PREPROCESSING", i)) + return + } + + let varHolder = {} + // assign the name of the var to the corresponding object + varHolder.label = line[0] + varHolder.address ??= curAddress + this.varList.push(varHolder) + if(!(['DB', 'DW']).includes(line[1])){ + // throw error, wrong variable length declaration + this.errors.push(new ErrorCalm("Wrong variable type", "PREPROCESSING", i)) + return + } + let length = line[1] === 'DB' ? 0 : 1 // data on one byte or on two bytes if line[0] === 'DW' + varHolder.length = length + let value = line.filter((_,index) => index >= 2).join(" ").match(/"[^"]*"|[^,]+/g) + + console.log(value) + // parsing value(s) of the variable + // we should include the number of bytes to calculate the current address + + //console.log(value) + value = value.map((val,index) => { + curAddress += length === 1 ? 2 : 1 + // we should check if we have numbers or strings + if(!isNaN(Number(val)) && val.trim() !== ''){ + + // verify size of number compared to length of space allocated for it + //but before, make sure it falls within range 8 / 16 bits I'll verify that later + val = Number(val) + if(length === 1){ + if(val <= Math.abs(Math.pow(2,16))){ + // use 2s complement instead of this expression + val = val.toString(2).padStart(16, '0') + + return [String(val).substring(0,Math.floor(val.length / 2)), String(val).substring(Math.floor(val.length / 2))] + } else { + this.errors.push(new ErrorCalm("value out of bounds", "PREPROCESSING", index)) + return + } + } else { + if(val <= Math.abs(Math.pow(2,8))){ + // use 2s complement instead of this expression + return val.toString(2).padStart(8, '0') + } else { + this.errors.push(new ErrorCalm("value out of bounds", "PREPROCESSING", index)) + return + } + } + } else{ + // we have a string I guess, we convert to ascii and we pad when we write binary string in the memory + if(length === 0){ + return val.split('').filter(char => char !== '"').map(char => char.charCodeAt(0).toString(2).padStart(8,'0')) + } + //ascii characters are positive integers between 0 and 255 + + return val.split('').filter(char => char !== '"').map(char => ['00000000',char.charCodeAt(0).toString(2).padStart(8,'0')]).flat() + } + }).flat() // flatten to get a 1 dimensional array just in case if we have a string in the object + //we have to work on this + this.data.push(...value) + } + console.log(this.varList) + + } + // remove static from all methods below, cuz we are acting on objects - static removeComments(code){ //removes comments from all code as well as empty lines + removeComments(code){ //removes comments from all code as well as empty lines console.log(typeof(code)) code = code.toUpperCase().split('\n') @@ -62,28 +165,85 @@ class preprocessing{ // input is the whole code which we divided into an array of strings let curLine = 0 let n = input.length + // we allow macro declaration only before code starts while(curLine < n && input[curLine] !== 'START' ){ + // tokenize each line to get components of each line {instructions, labels, operands...} let line = input[curLine].match(/([a-zA-Z_][a-zA-Z0-9_]*|[,:])/g) + if(line[0] === 'ENDM'){ + // throw error, macro not declared + this.errors.push(new ErrorCalm("Macro not declared", "PREPROCESSING", curLine)) + return + } if(line[0] === 'MACRO'){ let macroClosed = false + if(line.length < 2){ + // throw error, no macro name provided + this.errors.push(new ErrorCalm("No macro name provided", "PREPROCESSING", curLine)) + return + } + + if(preprocessing.reservedWords.has(line[1])){ + // a macro instruction cannot be a reserved word + this.errors.push(new ErrorCalm("Macro instruction cannot be a reserved word (register or instruction)", "PREPROCESSING", curLine)) + return + } + + if([',',':','/','\\','.'].includes(line[1])){ + // macro name cannot be a special character + this.errors.push(new ErrorCalm("Macro name cannot be a special character", "PREPROCESSING", curLine)) + return + } + + if(!isNaN(Number(line[1][0]))){ + // macro name cannot start with a number or be a number + this.errors.push(new ErrorCalm("Macro name cannot start with a number or be a number", "PREPROCESSING", curLine)) + return + } + + if(this.macroKeyWord.has(line[1])){ + // macro already declared + this.errors.push(new ErrorCalm("Macro already declared", "PREPROCESSING", curLine)) + return + } + this.macroKeyWord.add(line[1]) let macroHolder = {keyWord: line[1], instruction: line.slice(1), body : []} curLine += 1 - // this whole thing must be foxed later + // now we extract the body of the macro and store it in the macroHolder, we also handle possible errors + while(!macroClosed){ if(!input[curLine]){ - console.log("not closed, and main function not declared") + // console.log("not closed, and main function not declared") + // end of code without any end of macro or beginning of code + this.errors.push(new ErrorCalm("Macro not closed", "PREPROCESSING", curLine)) return } + if(input[curLine] === 'START'){ - console.log("code starts and macro not closed") + // code starts and macro not closed + this.errors.push(new ErrorCalm("Macro not closed", "PREPROCESSING", curLine)) return } + if(input[curLine] === 'ENDM'){ + // if we reach the end skip this iteration,loop will be quit also in the next condition checking macroClosed = true continue } - line = input[curLine++].match(/([a-zA-Z_][a-zA-Z0-9_]*|[,:])/g) + + // making sure no sort of label is declared inside a macro + line = input[curLine++].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|\d+|,)/g) + if(line[0] === 'MACRO'){ + // throw error, no macros allowed inside a macro + this.errors.push(new ErrorCalm("No macros allowed inside a macro", "PREPROCESSING", curLine)) + return + } + + if(line[0][line[0].length - 1] === ':'){ + // throw error, no labels allowed inside a macro + this.errors.push(new ErrorCalm("No labels allowed inside a macro", "PREPROCESSING", curLine)) + return + } macroHolder.body.push(line) } this.MACROS.push(macroHolder) @@ -91,9 +251,14 @@ class preprocessing{ curLine += 1 // move to next line } - this.MACROS.forEach(macro => console.log(macro)) + //this.MACROS.forEach(macro => console.log("that's a macro: ",macro)) } + + // this method should remove extra text from top as well as macros and start / end keywords? + // this comment shouldn't be here + + replaceMacro(input /*it should be also the whole code */){ let output = [] // new code will be returned here let curLine = 0 @@ -102,6 +267,7 @@ class preprocessing{ curLine += 1 if(!input[curLine]){ // throw error + console.log("No end") return } } @@ -109,13 +275,15 @@ class preprocessing{ while(!endOfCode){ if(!input[curLine]){ // throw error and quit + this.errors.push(new ErrorCalm("no END keyword detected", "PREPROCESSING", curLine)) + //console.log("does'nt work") return {error: "this thing doesn't work"} } if(input[curLine] === 'END'){ endOfCode = true continue } - let line = input[curLine++].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|,)/g) + let line = input[curLine++].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|\d+|,)/g) if(line[0][line[0].length - 1] === ':'){ if(this.macroKeyWord.has(line[1])){ @@ -150,6 +318,7 @@ class preprocessing{ } if(newLine.length !== expandedMacroTemplate.instruction.length){ //throw error, different number of args + this.errors.push(new ErrorCalm(`Different number of arguments for macro ${newLine[0][newLine.length - 1] === ':' ? newLine[1]: newLine[0]}`, "PREPROCESSING", newLine)) return ["error here"] } //there is no label, direct matching @@ -162,16 +331,32 @@ class preprocessing{ } // no errors are handled here // no spaces allowed between labelName and : + detectLabels(code /* */){ let n = code.length for(let i = 0; i < n; i++){ - let line = code[i].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|,)/g) + let line = code[i].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|\d+|,)/g) if(line[0][line[0].length - 1] === ":"){ if(line[0].length === 1){ // throw error console.log("error, empty label") return } + + if(preprocessing.reservedWords.has(line[0].slice(0,-1)) || this.macroKeyWord.has(line[0].slice(0,-1))){ + // reserved word cannot be a label + this.errors.push(new ErrorCalm("Reserved word cannot be a label", "PREPROCESSING", i)) + console.log("reserved") + return + } + //label does not start with a number + if(!isNaN(Number(line[0][0]))){ + // label cannot start with a number + this.errors.push(new ErrorCalm("Label cannot start with a number", "PREPROCESSING", i)) + console.log("number") + return + } + this.labelSymbolList.push({label: line[0].slice(0,-1), line: i + 1}) } } @@ -184,10 +369,20 @@ class preprocessing{ let output = [] for(let i = 0; i < n; i++){ //check in each line if there is a use of the label, if definition, we remove it, if use, replace with line number + let line = code[i].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|\d+|,)/g) + console.log(line) + if(line[0][line[0].length - 1] === ":"){ + + output.push(line.filter(word => word[word.length - 1] !== ':').join(' ')) + } + else{ + output.push(line.join(' ')) + } } + return output } } -export default { preprocessing } \ No newline at end of file +module.exports = { preprocessing } \ No newline at end of file From 0a74d7e5d63263718b297116599b2a9fc06686de Mon Sep 17 00:00:00 2001 From: redouane-bensaci Date: Tue, 15 Apr 2025 20:59:54 +0100 Subject: [PATCH 07/12] labels macros done --- src/Emulator.zip | Bin 0 -> 27555 bytes src/Emulator/IO_Unit.js | 40 ++++- src/Emulator/Instruction.js | 218 ++++++++++++++++++++++++- src/Emulator/MC.js | 85 ++++++---- src/Emulator/Opcodes.js | 19 ++- src/Emulator/Queue.js | 2 +- src/Emulator/Sequencer.js | 2 +- src/codemirror/mode/myLang/assembly.js | 88 +++++----- src/pages/Ide/index.jsx | 19 ++- 9 files changed, 378 insertions(+), 95 deletions(-) create mode 100644 src/Emulator.zip diff --git a/src/Emulator.zip b/src/Emulator.zip new file mode 100644 index 0000000000000000000000000000000000000000..82d84a1a1553f9ddb507f8127959962b7910b0de GIT binary patch literal 27555 zcma%i1CS-p((f7D+Oci!*tTukwrzW6$JUN*+qP}&=? zGt&7%vwyDg{}KZUfCOOCxT*iU7_@&EBVg=k;^bsuYer}3^nVi>Z1H81FgIxS&-F@2 z%kH4v)pw?r0N6Tu;cgX)lq2HAy=6KVWU&_$Rs4m+XO*1+HA;4IU6pDqLmK2et^3(6 zn@?5o=f!vwjYfkI@8sY!QJ1ZD(efX0tqY8eyIwB!!ltW_%b@o#-gF*+Ty@T8ENyu3 z0gMBvwt0uHJ&k8@?!uq1<~E+M-<2;g z{#ikt)xUwdCNAo90%!7H4B6>2ZMX$jA;wS7EqB+xuQ`^F%OUPy+}=+;Wp5^~mR6#+ zeBB|ss-nR%J$XJX@YS)CoOkl^dw8&?(IC4SrLG>WM?8s8ef&G7#7o0dS*)Nu=ic?1 zGC&7(hw{jaAbZZNJ}@=g%EB4`4EsB#ErNbk2#jjjvH#$GGU8om`1%@f_4~a-Pu(c0 zu8?)rexvyv#Bid|&fa8eW-Jyv=lmlspSzMOdbSb8x#ZCpgUoXw8;3H@_C)P^#!ib?uoHOO;1Ug%aA%Y zR3KE zQ;|+!XOk2BuB*O5>eQbzJQ3@VlU002nEK$vw@!yI(XCzm!&a_`XBN!2ai=>y)QqH9 z6;rV^V=M0Vi|y-9ZUqF5>QfP{=&)xO(+cC$$Eg|v8ZTzwL^R(D794Bh^uqUo>CvQ0 zRYJ!CRtGLj2xU+FGDZNQ%q=KOk01YZoqiYE|N93u$cNgu-iW<@WiQdzpPlEg=&Dk) zk1O6a`m|5{)H5CPI}2>!l$|=Zl}+Q=EI#SZNF4g@ut4f z6MLu$aw!wL7^7gh67N9KmN7rBnhS8*_NVBq5PpVnldPomjntzVOhr>UEl0I88C5!~ z=A4bY*M=s(*p9XIrjv&47GC2IQUF^J6ixOL*lKxXxAd&>d_XTk- zFRHVeb@ax)Dd;s3uYKxgH;4ZDHno$mlr#4Wyu*@tpX_;SPP_{(&Mmq;0nay2PRUu` zZ$H1;wtGp+Qd36RIuG(L^nar;11!YlwO>TO1{GXa**4ZY_pUwslzGwIwfPII?kC;e`J_lqp!m z&op2=jIo_ZYqr;=R>*KG+G$42ShHrs$w=#j%6ygvwR?=SA?^`XFu;na&MP8=$zNV^ zKEKD5#im`KJ1tyS9XQOtGh`2hqYtfjH8@yTdEz~kr|ayf)N30Ph%43hTe3b#=U1{a zH5vg`yrzI1JG~VEaw%H8nHm!?vg;12i2pev2A|18UUx`6g1dM3Sn>nDcymjH`Z8xe zWMl!`mqD2)u9PHfUA(Wcm_mdydAa%b%fbtB`?xoj2#Z1*It$i8j+}x?_Bl>=KNfok zgj0oseZ_KbxhF#@6-22fT(%{I6Ep|=lGUyXM*HH3kIM;Otn06 z>tS6IvTW3fS|FdOwmLWEyzeQO>6CV?wNpE{$sFMPRuF=cr5d z)PmcF@bx>dC;LW-8CTcfk?i*GBlzXuOS@sqd$GuvS1KB-F3}Pb_w*vOSEE8+2lfG> z58(IKp({{rFwhciIpBcjiXO5Ih<+VK`~g zFRd;CSMi&KrywiC2iUpaq{j9$uk?pKtG|Ue2TO-@0{2Ew-U+?H)d@zJZ)d6B$NHl( z{oa>f{NA%1uf8jH`=s@@yt-;)^5Vj^d5;i|=`Jz!y7?`5dDeI50)X&ryh5Vkkdor} zfoh?ZC9iLZj?<-UU{tQZTUzFKO)hv}B%vfGMv8z77^F$rGJY>38RlzK@&k1Ntk#odIePP&^KS?-1hgA#D zkF$!c59`L!`)nUb#Y<8M4V73(xm>&uKu^tMoUb& zA(i=h_~Zp8qd)&j&S)WmhZI9pKwe=MpNjDf!~+#|^MZt&_lStXcOxC?Tr$mt!ZAa7 zEh|9J7+h}DFc2wd1+_#qFBABv`a zfy$QxYksD&FBF5J80OzFVZfu}Xc*G>$zhl1rcYf=hZ!2q0>?PL>tfREu%c@u4^NS7 zPL3;dQGFP~YO7rT@mWFFv}sI4Z#+=DQWz zWi8Z(-bKx)i^2Ov;PXm{wO>=&jO}-KUDc zd!u^t#^W8;n1z*edAEQ(OleUFEf3QOvEjH?=ZsG!n#+vl&OW z8dUfYAf0MAt;Ra?cz?o>aaIK9upcr8V{PxWyy0G%NDo?p#$_~*=}-#I6s?!q&O)+| z08PA){ZP@rm?BL3ycY39UL||Nap3Qb455>ZZPiYtIlHq)`E&(QN{)}D65@B_K2F=K zzHmN%Q9ha+VPS2b8^|l&8P}m?zn44VE}%T&D$;k-`6A-(%Jih4jz#~)F3B`bA9_%r zLDU3W%S%ntlP%ZzaF~SR9KvBTU(m^PI7v-DhzmbrRL~^YbT8QPar1R))*Mv{Put(& zc*6=bZ9wJUc-S0P4c;Txxo1F0Y{)6G6_M!h=mg^3a9zHZINUfjL20=CdGrWO0 zytpL@n#~(2J~)aGFF^vLUE}i#fB*x*L4~$QzDI3R1<@YSmuqtqERyUzlZA$2CQi=I zM%_B|-Q}r){W9Qc*`wT%L1!ApVZ?zN!9q-X&YkWcx)HsMR8@kr;Z?Osywq$f3nFalygN zrZQq(73FvJGVR8>Ve^uRb*0->b48hr3gbq_Rzo$Jsg}%Ov*wC5jED`)kTpz)iI&P_ zb49q#Qq7twQd2dNsaCO8bBJMc2vIYd!vR(##)sEP+n0iCTqDf!zN}f3UpCA&(|E0c zwBv-sH<86vm8jERx{7a`VWLru7Mg^WQ4b@AcFK6I^gjdCh%DMpT@r9l`9T|kLtCKW zPWY9iyxrSik@0i&yR}~Jfl`_Nf$kq-a1vi2aMgNa9RW8Fh&Ki-fz z(Zd}c4cT$N4*VGBDs4F4YUyiCli{-XCKM(g=;+O({k>SUA2sp+#55x6h=y)-%J%p0 zj%4rfAtEN;;B-*~M-b@+J~h<$ffFu#%NTs9)}tL5MD4j`sR_6*9X|p5RnXEk7A1eF zAfu2nDul=w79jtvBxF=;B8CO8*3^s&5oC-C{{qkcHjqyKYg`TqnWSL>XFxBVp0 zIpk-JgmJ}ZxLp+X3L0-TbXS*R1p=fnNGUpInk)u>i{}`+MIJfKKe;*~-ENvGq*Wc8 z4?ynM9=BYyQjh+*>TeEuMI<_H(ohu#(;lN7Cxk26VOMfL;D4nbLA#b0M07-{Y5kF_ z2g@%`j|A3?G`B?P%~ET>&$y&N>%nbN^X|G_SnO7}x0ZTVMr{&f8By-|E|!ko&W-Hz z?fTK>)LEWo8imqp_}kQ8tuM^_nb39zuzrhd4E8p zP$&di4k<8CLDAPR7nKnBr5|#0yhU_FIVSZuyOAIe%nU^Ydhg2?AtLQWT_3(iRv#Wg zNP^C|@VBmzpeq<6z2K6dC#*ChN1gusI|!bzKAcp>5XtFpB}Hc}NmUn)5TQB#%B~A% zCNy7)t{mq&D7&AQE>&^pKmUq;5Uj^s2{E*RAw`Pty3P_InI<7}nCTEEQ8mybLMA1; zlQ$qCQXoP`Ko$IlRRAuef+j~CE?NM?EM7m<-qL=@B4^H>ssF?YcwZw`Y=v8Z_2gl93hN8R7w^a6bsxO1d^j} z*~(Zm6r!$M_p%x!7ZxI8v=7=jXaQf}zzFLD>pOreeRvp*8YKPMP%8R*hN$N!UY;}4 zT)+CSM$_k{1;^R`0dCdo?14RINBP%9rZ(`TvD&$)n+1s3I9-avq}!V_!vK6zJVq@o znpXsxuz;qx?BXl^w%eUh3r$|PT)5mAHSP~)B0KQRa|5*9t5d!&dU=R1{3IIxE-*R; zu)S6F*Dt>mW|f67_FD#%5%y4_Z@xc9hT_7ScMo=f{tw(@4G`GLY5Ciw1yT+kQ0JFP zMy3RG2@*z;S1|o<{lptlaPt$7qh@oLau6I z*7a^0K9``M)&4SnU+7Nq>V1_z zjOQv?A~@qzXidIQ<130MTY{CQzUQkPgDqw_5#o!FvYtmcv3G;w)0r;Ie~=qvaU=@l zk&N)hC)7>`r{u(Mz`A(W9l~irtO$pOS{x6R%ZDFU57$@NPp$Cy(|Du8lfd9N+!FpL zQTUVdfBK5X`on0vg=Nrrc~5EeO68m5GrroHKMw(<5(ihsWh7d#rZf4M@BEmIbc~jF zydgn1-597`gr3S1`H(kCn&Czg$$5ut^$SVS-6C6_WaJnYuF5l)1@VR~aLz z&|-KE+5)51Vm)^>rwa{2v8qlOHv~8lodTxHmAbN|Nr&{}mdJJW<=zlc-z)UaVPx33 z$c^Y`G{UB6=ITQJPSASb(3YPpV`lt$u3Mbz zOp8c|odp-NZP@kOi~38aR#mg`ek&bkYJ`W0GY#s~`YExvOM#o;ooKi#{TFho<)15T z9fkpxF@NiFL&0`&Bn@g+!|gO&sex8zF7z-*yJw`sv%zb&yLcZR*DIK`(W1E_GFm3m z3;65wZNr_RoWmqna<|3U*Gl@yiFPB;C?5;AM7i~&Ed{QU?CcTJeOvUG`UsL0oDuQ@ z)wJ8-l_KoALtxh$)s2QfF8!neR&{W?~`^dT-} zvW*XkHRi*~d|%($)&?ngN+$@W%mrPI69%p3aaTnac4r#7uAR|0%u~S}gtv7@&K}&m zpw2QyGmvanRIxrpWOgk!c%c;clUSqz%_TTNbK^}1U-CByqIMcw2UtgrD&s|S`TTDt ztcS2L90Xy#Q4r%`M{W-=1%P}`L3*A%2_jquM_#5w&3N*DZ`9xP0gpUdoBPt3&;*)a zyTkBFms1rW#wPmS%Io*gM*@7aw}O*E`i-0 zVuSrIkgz5guL>^V2&_>P5RU+Y^8j^EJ>W`9^xQINf#759*SM%*hWTV6O|s9j>T4#i z{UZ2*djJ_|#7UL;em{^&{u^_>nh+VAW7*UJlzD5q;YTKwiCHB9ZnoX$>{?Km@b0w) zfl@c*r^$I2#7VtoHy!AAosBZ*V6=&Fbw(ZuK25Jnd>;ary4D?<3_3urk__(Dy#-15 zj0N%Y;_MF0!sJfmbZZKg+q6;?yIuHUV zBFbo{X{CEEa=;j#K#CFm+3BaHE1SO5hgLh1%fO9^;hPHddNJdlYEba=straIA0U9 zJ>S?aZ59W%WE}J5orjuFn`3n6gV28FECd#qZCiov`1+s|l=Xz2!KD)AuzjUu$gCVfc|Fi6eoB!^`d(VRfA(Y!F37jzyhic?l4a|qdL zCJndn$jwr=OBgTOThMWkP-IB*XivutM^1n<0LgG~UcLzvXVEe)E^|7QS@Fefp<#=1 z?vhiJI#USK_zUR#N7biwGZRCDAkF8Isgb>6lyjQS0*T+Z%(h-SSU!Gx2~DOLcXjm0 zAI$q`sM3fzXX5g1$ZA32bKP5jgi0OKWUkGC{EwpF7q2v67_`tB+G=&U*=#7jJl{t5<7oU*ytrYAk^9ASCiG)|_NK;? zjD!z`2n2m56&7O2Tsz{ShPz8(hvw%neF;z5hTDPVNKec) z2)~4kUI)b*Y|)OnX&O+eWkVj_E9BxdbgLf+KD3xrBl}6HyZWpJ zRH=Vbw}qsj3jo)DWbR{$MLXrQdBs+pVAs}o)MX!>p+}G7(=a+a0e>uaV7ADqNf_eR zXS0cvD0T5|umy)81ls{#%P_=iAH)TYSqf>iY-i6pUfXMwYUW*Ih}J2^ys!uut3ppp z%9i{|Pn0rsluiRTaqLUm_5-5*Xcx?}OpbUM_#vSwCzCONw(#a?IpCJno)oo4GL3eX zW8B3Vs)4U~ff{%?uODq4m0@UF-%hH^9fuugCMxUhQS;dI^+1jTWy;9Q8%d7%yH)WMivk|Cv{-V)y z_aU_YTHL1E;Frnb-|x+I3kudv*M=Fl*dU_9Uz6`|CvCQRi61XDU_N^$$~HyH@yUF| zvd229-N>=rrw7kBE$jFbA`ar*%w`ag*(kVOE!3?oZ3p*afwH^>V)*Hsf4z-$ZVLjx zH6YNXGWhG)^_P%5dHd@)4VDS~k0xzz6SGi99Rw>9W;9t_6!MmoBrB>h3YsEo<8MQ2 znJ0kgUQkD&(HLXJ)f_(e2^1qA(GC-~&tU_cihu+xitza%cexvD~P&p;}ro3j9*lcdMHc4UAzpkoWWFZMOd)eINkiO@u&`E40Z8s%lDdJ^REpd z!&@zPB*ieJi&yu{BxkM*#`tH4@)THp@HLMeW`_^sKTec~v&YlzenqdroR;p3yktkF z(W`gj_{}*&Nj2E-j)j^(oSWp`7sE(Q985>%~)k*D{`fw5-ff$I{{nasLi523PrfJ74-ks8z<7mzr z-7%%V8GKS@c_vj8y%d&oSP#j{Trp)a=uvXG<~~M!ykdS7Xls}q$Vtd`-GIjqUQYo# zj=Ak1P02*xKgC_XhwoBWE}JN;+*fKHxu|+yuhe$)w5&(C$0Ql`W0&nRxLbj3LOHwy zu)7x=-@0bc*^JH}XU{&T{E}gkyJO}oQ2%KywsVVm(e3+)M*DLlpaUYe6f7Ih9QjaI zp6lAnzc_%O9Gepcy)SwYJM-1ujAe*xQzY!+XKnI96Hf33!@?#>sH)nArj>EUQ|NuQ zq4Al8o2q6UEwpA!KWw9WqdVG$49_2!|jXF^Y)eW}`nE~}iZ+aHS`HmAA%M0rfWQmW&cQebF zpzHdJM5K8Io(gKj$F|{1A4#P7?X-cc+PRtJ{P?J|ueGM9aPOs>PVKjMc5>uwuV#k_E9zF|@+CLUy=Cz7CX={*AEm8Y4cfV_T zq94$Env2idf<6TPc6SaY+I$UXZ?TpXqnzj)u=KF2SVzvGeCf|=x1LUZA7}vyj;cwg z_KC=hc`jj@C13PTbrHg(mr+a*@_xUqGqF@sQcH`I0n+@i3yTbesk|#oXvuj?P4}{!t%-i@T{iQT@jAkb1LwmsiLl)U32ob4=EUOhxu`5oEAv96!K8;C0~ai zxs_KH#|mmHnxp+!S2}Pd6@-?4MLM!$b&iWQq7^~#Hw;)LQMk+bB?U50doHNdhx={2u+QGw$~xNP6%dkUYN|E zTnWycY#XL!JC@CXg}NdSti$y5!WFxt0Bs$Kb@Q5)>1jNmiW&h=F#VNboS*B;eFx!3 zpJH{=c^FQ0uqEf3CG?MuEt7nsb=RWUCl>KFiw)9&-*VD{vw7sg6XEZlgNnY(Z0Arq zr4x&2zhUwS)|$MsPNFQ{X_bnZlahy}yAIIhCWEswZIMhl(cdmR%zO)UUtl+=Q)1W} zL3u4mGUgi$J59n~UO3iOxSKoRi)wRvREBKfRi98?sy%7Kxqhge!gydVHB+!1!{_uN zYoS_2JF(_&v5(8STroRSWpTufz&?M%(q_*Uqu zm8AKp9Xpns@IoJqox;TR4{CF!;m(cGiYvMb9RO5Th!lU`IHWH%8Weg%dO17Qi>;U; zP<|V%GJHdxx!NG2aDuiowTRc=z$Uxbr|HaW%PloQ?#yfv9GGpE9byscSRD>&trcEY z6LP528?UT9pgjFjiEW1Tj>#G;iN00^zvtZ+>0ZqV&dRy)v&PM^;PWLc+PT}CF5WF# ziA5nI$afO8w56}wNh({1r`{;6ck<#FK37U(WN**Agpym(#^ra%z@w|h`nmk3dhfVj|4kFDjCPQG{F%}83Y z!Fsy*1f@ixp$;+76bUZxA=FO~Rlp@jX%|GY>B~(fGg-TdS5JPHWq&x%XzeER&i}&N zxjrsy4IhERFZxc%Z;lRJ90$|Om4Q}Er?}0qfL)-fqh-&kJJhILKt_~8-8FvyA$D|Z z91>mlyl>pLt8Pn&j#q{7;&1FRWKz3DNkkWh5Bc$+l!1})%(C0Xu1Qy)(UYZ-r!hah zLuqa(E<)xxTY77J3-m^itUVm!9jpK=1a*`?r{L&-9^u{hIYuaCzYFQ9XRQv3^XWYJ z5~D3RxV+uj!h6v>MAnCghYd@%HO4~`jlrb+gB~@%?lcWi&qH2DNr#ur2c^Di5vUk~ z`XbZU1g>X5v!rGBh4Ry((LFFJCdMYZ%oHmU;{QG6^OKAEwlt#M;#h9PDMvX!G1iT{)wf3SAR`Bx z<=0oyJ##!ET5JmU;To5ca^M@Vb+)eYE+60zM^U{(3Icwr-jND!<7OWe3fWQAFx%BS zMOb%lN#L%V-}H4|*v~-S+J|#BN3K&(o1%7*hIv=SLu(Yzw)!Cyo(1+y0_tEO2LS=< zU*O&3mjI9@n>}Kg&ek3>-l{)}&3Bhy3cp2lEBLKn1~o^T8%I{*%e%Adr!MiIBCj0Q zDZk$#ue)b2mfXy9+al%%Wz?UFVQpQ%%Tx@Vl|yE)A9DVLKAYzy;Ldw<5NECNSfZ^h zKnp+DQ!KU4<;p%|tQkzDF*U4h6{;ri&}kXFWskbL;UvaRtQfjQzC~Nu;iNc_3wwPo6Psr_b0h_gW!PeKN_6 zNZIDGT=Ht85n^L3E3IK>aByu$k^<^9Ad7;!nBXZwKJ%nsNGGW_Tcj>J`V4c{Lj8!` zCoN?rWyhX>*kX#7DDXc1e3Q$a3QtXk$^=DO!URT2&^T{pfStnpTTl;ZMd^7is_ zYJs|~{A@}{4(vF|vXSQKKIob9s2Q;>26tXl3Dt*x=TdHFgqL`b7v*y(dFf3%Vskhp zFQ#(Iuvd%%GhtlH;}sG;UkX1d@m zAaB>`Txfy*NPm_WmPrtr1F_tsI)lL21(<7U_m`Lqew;SnMUT(Zyzn3jq#E?H21E_p2&)Fdo`TZFoJTF6 z@m7zmP_Ao>;t5+I7r7v-P-^p;Ulf%!i07bB+h`p2#|8@m?R%nP44^;@N>8{_9dM>h z_zhZF6_i$QJ^XNLZI(4zq(+@9)iQl;yeA20toc2M667RtbHlA`u}1U25&U zi5{_kTtm{_(XlXW^tt8Z|Jqf{xpbFf2yS9YU40DoQ)K8YF=GCEZyY<=D z`rAqidar6dx<8>Eu&*kC(UDVN; zKG40W$~d;kIbB9O5T%7T$i1k`9qcGJp*`>@<{FrzsB1tr(jUlr7!KlpdI)bpMlpYJ z{v%OvTHHTcp%L|f#}MlVX{}2vI9efvN%Y7CL~;HV+&CIQKwtza3&12+Brrl%I!|J( zFuoKVhRg;qi9&w-C1tX*h^d!eK$ye; z$k87GDE!0WsG~oIlK&V-Q(<<*GXj(QMlapmdEElA30@5aCEH9})KCZr&fsMM9$KKkH!_0XXMb;0{?*+a zg4|!5_OI^F`2S1y_ISp~RKdcfBaT0a@>KG#|S^Ys^PfnP$7$mLOh`P_e!1Bdx;+98Qlu(f@N>z^? zpE&%JAPf`$1V!@KfOrYOYlZ2GS(gf|Mi`1>yP)wu1$QChSp;1i1A|^GgLZA+cY>b! zKDF6kS#+^Vy4!!M*m!t+iez8srQ1IEOk`A8QN^-gWx-vVL^I9xvXn-Cf+cTt{Y6K3yRVY z|F%>xT_|OWy}`rF4XqL$w>f=sqjupX&Si2}r=^Wz6{762KaM+uEcf6mEhr4>^Ou{3 zM@Q7Hf*L?Q>(5CHarl9q!iFTGp^PXzGeKKjhR;clq9xB~t2^ABi@Js)B7qLvWA<)8 zg4|b`LF2DQkNvDcW6l08_I-Sp`i9_j+Rb@=z@*IUx(NppE=5zRk~#l-SB6qmiu zQS~iMHYFQb_M*BYFG*b%B%AIcs~tIS^LgX&(WshCN#-|FmSs>`PkJjZ22l&EK=0u- zHevEnQ%yP)4({-;l(|dgKkbjv8ycx&_B0o>pVc%M!R(6LbEEA_QJ7il_MgTYf=y9Y z^;IaY>Fs>FQ`H5iD^K+eEz*}>teE$GYxOgmR;|W(3))Pv77Zx-Gh?sE-cm1D%pPb$ zCpJoUQY%w6XahcnvW7n?eErc|V1$1*X{tJ(4}0 z!xvBhDs%u}0`8Zv>MIJ+*C{a2$J;8z>xND^!ukmcOaONT?mda>XcFN5FLd}98vO@? z_E1EMA7ROfvDl#CJ8e^1kB!wueI)Tyi!cB6PVVtmrjBNkxWh7=R6zaR({+ebER8Lr z5vjjwJgzv93RiL;u6U7>W`-h4Sd|GY81Lzy?4OJTH6EOtLlo~g$h)LJ$hn|jByIMJJp=7>B#pE<&)$K4e|N_+VXe2g^?bqVD1?CYt%qTWymLg z{LEnx+;j$p6vKc-oF3sN*t`~0hS~#GgXr6c=m@+2*g&E?P6{+V9|$U-p6~+OqCAc& zph4>H;-^3Nj=dpRYJYaLIMrB|iE{O6#v4+kx?>KZHz;9PklwqOMGf`nFS_KFTh*y} zBrxi8%O<^yR1BSg;`n(~{EgUa4tr58bZiGCG;9YnFxd@OH!i?d(TdYBy0^SZ6sA-w z&vDruKe^eFi0P%~$m6LtW(8GFKW3dndLSrt0hQuXPe|$O-I0Cdz%P`jAYt&cN+oNo zwaEG>1LfTGXJ+bFa;qWk%oAkV# z4eed&%zAlg--jq)EZRF8qk8vOTXB@`pXK6dESsNrjg&emd)`AWWYiwhC=Km@UX6$G zp?aNsGrFr-Z#9`6^?CkNEqa9*1+3#1ck+k_V4g9 zn?MWaMb+O4=OMhDx3lIPVCp|--~y4%VhTpUTkI!EfYZR#ZAqyNHN=mUBLr0--Hq0w zPmrwW+T^U=bT>8cwA)==%}~S)xJ$LXZggLaVM?KRT=7d2x{7#`V@*Z7br-FRA68%h zXKsOyIU)9Gm2Ks`Gt}XWgJmdCUj6=L@T^U&2H*AZ!Uw9%I-Ot%>CIAPAKgFFxaWkj(HPpVfB5i}V+iZX z0eKl84gI6M=u}=r7psunK z4Ei>AfEPhWA=}}^Gck?(=4XQ~L9D&GwMED=$wMp>)VUPDw$c^gCPyM+7no)aAcs!E{a5mYf2YE#wgH4O(W zE%?-R_J8XFDupgVR51u4^jTH>x$83N$@Hcgaj`E1Ks50x0B?=lA<@X9RlFRAPGfVv+zpdqU%eEB|DjLRSa)1Tj^pHM@&ONr z$(S4i@F09WLby&aj{mAM(7nK=py!H`YF>6j+o3Zbp2qR-^#9O@M%G9&`_}KX*!1DE zwx=lP`n!t94`F(rd`Qa&EqSU1)#~A+uuFUQ_I8nXU(!p}*@J@^`_pLtR9BbChQp7v zRBLSXmlI;sLAM&LdOLN@4M?^szN|)ZAHDI1=i$=kzLsnk(I2ek2?kw;2D>F={k%nL zUUq#-dFA+IsQ_qoMtRRF-UjIM9**HTTi9w8JHQCg-=Z+h4nGl06nI%DUFMGl=702G zMVTXgWrv}rdu?Jp3z>$PO1}wcm;Jwr3jA>sM>Mt5a|2x|iBxoK?C3PtC|JXmf3BTS z7!L&ofCtc}muMJ}o2@_7h&5c<7UEN?Yw!SfMl6e;$0(NIrm6K zqe+#425KCv8m&>)S3+NX-w1!1Wo~HHNk&POUoY7c$z*N2rMq|j#>yP ztJ))c{>j${yZ~N&B>>kxmjjkm?LRzfN+iJ^A^LhwE15)DxyG$gy%IAjm5CcTjXs97 zEF4NUVcgCeFq2um$tLC!iWO{X8jshF9`cIVh`xCWd%6r9J~% zc5K_&3XSo?{JefgB;`f8pXqIubh*C=apxT1>`)lL4#Q4w7;t-bde@wX@~U<8%E9h80yzL2 z((yqD>k-W~nR_$3LF@uc1w2Q*@S3mljD5^C*+CgV8Itz}{0U(~hgpMuIczh4f-v;{ zVnG0gUt?Ep0a|_Sgd`FC7I?%#0*(fbHuOPc7{_Z^f-5Wm(^tl3fc{&k;6xMrknJu1 zyo+?%L&HpVmJ-Hhv>6&!V}a!1@xBGe4W_p&{5ss&L{z$Ekbw+}Wlpgnp4Fc%(a#9+ zOiKBit<%u)@n*{UNuPPAp~XFu64Jnu#f#VG`$|d&SLJWYciCesxz+5pUO>{BbVJsS z`kjr++I&MK>13a2Vl7;}IcY)^in?Uv)K0L_> zuwV4y&kn>7%Ac*h0*hGR`vfjr<-ZS<(AjwCFOCBOKmy$TDX{f-S8(I+T!kReO~yww z7=`t3?QHKZ#~?5axPS{+2O0t)@~{{KN?->E5CQhz>{vktA9gI^!%upyfDrGbCg8(Y z83Bk^2;qk$y#`$bbI2T5XC9$Ge{#ayt~TV|xkfIlqf2k*oSyebZ`b0H8VHF^g+#|g zrOC0GwyZ}VSI0W>TaYfSo9S2d&e6No_p4^QFG+FT+F<%@mqEESP?8(SC`@JKM>7fX zSo_#e`jX9eMZ8#ge0aHqlFh{y?ZrTZ5!}ZSY)6%Roq~AxI0*MR*6mzRm3-|3@xO&( z{Jc8^8u`HhAH<;mmRGcp(uRWLZ|loKOTDy;i0>B-t<3h&jM;k3=oKN!9oq@wSC>^_ zNoPoYaD~(ohZq7lodh$#m8K!{r`!C~UpDg;K@n36f1ZUrtNjirNk(r84*KLD1-_FP zhbx=g)$ru)2rpuG57${6p1r-Ke0{y0V<17oJClS`@n`;S+gD6t)fW~$k!hd8?c^oh zO>uw*6^B-c2zBx;i1s;y>pCwfkH%Ugi|@;q?A0a3ZG2^nkEP(xWZD+|%u7R1NQd0DyWi;D5_J<=3hGN9GCTKQd2pdMdUS&i_r;DJHAqe`lShRAlV1 z7!kW3s6{!HrKAE%I0%}{7nMZ>EQ3+8ju4OZUCrF8v9i{;0h0GST-!G~@*-Xp2&3+% z+tDXHGqIwGkfyMc7;cGL?$>h>S^II3Pz;M|ooC=6rY&(!hHBBZu^u~J-b z1*{uhC{&#pw!E6XYNXYwf~}1|r5nf`Yh8wQ5C{L;uV^XcinWF+NjRO$+O5HoBq!`kk3|C#mXVV7ED=}ZRf zHqQ+QzugA`p|Rc5Uxk=+L}9GtD@6V?@YhO+#wFYWAGRP{FYrWO-M|TL14AjZQXgfo zC3Hr@gM;Wd#GlB3w^@M?lu{51toxk#W=3Oh6&I%~gEybx z|2Vaj60?XiFaY2N@$czWmiD+ZwGBDA9C)<`T0JEeAt=~c6W^~Du_!0+9J&EyGGNd68Xt}-W% zAq_>T(x6TsmgqqBOFtu_p8cUtx62OXX41}*dNFBBuC>>Dw%Mk9$#+ymw7=WkI;>h^&{8|rNSiko|uZF{+kbG#@mw44-- zpLX@MSdRbDtxt*;j*C9WD6t7=45h`X--8VSYjSFw?nE#_nFJl>>lBMj^)sg7DtByI zTX#&TK<*h|sltCWxGkP+wLx1icVRK-Ne0Q6Z$)&Q%2=qj7|kX;tn`$puC#wPJ%F#S z1N@}T%t8XTFdDn)Dyv_XN~f*Dj(79gC<<3dm`B2s@DHLv|-p^9j<&cmg!!L+`tcHC#f~E-s08D}WyVc^_{vVGbIeQ~JV-u(U z#&o)s9sk>OKIuAk>kO!&HxJY_HJVVg4iv?-`vph}*byO=0q_>K^2Lg&HO zhMXtMjym;0IHTXP^BEe=f&>y(G(t_n45Yn1;hg z(b40q>>aY9uNID4N~T_pSUXv#pVpByZ<8xak&4V5U}nl3ZsVd=j`VZa+e~tbf~zN< zVTT)uIQK@*B@Cq?%-f8rN@HL*PFj4E-owIHX|6S;n^VmxaeVk%f|h|B;^@VY%PYhp zC(^&+?qX5gBe`JL{IS^@RGA(rbn48BBMGH}p|ExDmIAd5sFzP@8;o5|LJkw(+<}_M z#lEb6Y~4;JA(VZ`?t?0xz8iZx-`Rx!S@gDFLY70Zh+JYAm!kPoEuoBKjR{Vq9_p8z zQe~%px)(*|S!K4WX97u@-j;l(AbemxHPT_3_Ckos%hO35$EKGh=fr14 z?4muMUN-Z`B+Rd~CF*L%!J$C_DYcd|t3pX@{TlND6nCqb5hdi&C3@r>W*St~5X`3u zoHe+`9Nv+NbqX(d07Z^CqBqwm&MPC}1IgP_g<7E*K29Q7WknE&5KhK~^e!?9_(yY_ zNKdrfKpI#>!kQiem*1Gv1u|M@o+QusTEm-90;DAju1TC(VGDlm6}C>kMOE>wveKab zSz-UTV-(asn^`3nQy0^JQ(fPkq5Pwz1?t$?9XDXSWa)RqHf6S#jVxHZHkvc-C=I~R6wFg=~x&8B|jB=u=bgrKDU@OB3asW9YA^$-}SeOJGfnPf!8HB3= z;-cYo;e9ItIwAQxJqahFJgNP;?ea8tuwgJcwWDeuzcCO?W9e zPY3iBpqqkPl=VaFswD5G&3C&i@N#IdK@Rr86$5N77m2!1I1>!n1Aj8(n@GFS9ST&P z6Nhq4MoC7a7kwJPt7f5_~il$3#~XTg!GC%ITkfl&+aA#<0ip$f$;i zsmG82#4ATQer(GOkUVks1H7)~bh{*?on8;)cxrAhF&W z+m;X!zsYOOf%}bLS8UVf@^XP;kIS3vJ}x(6``}$|{u;4^=f~vy9ypfAE5U%=~b`WANvKxdrN1!kqN|4=XVesSb15IIv-Fxvn|my1|0w?(l zRiadj>Y3evl&UkNSIOVpvc7EeSoGIffTu)>_ zgg4oI3voSZB=P;s3ajkyEL>tw>HajUOn1-+M%eSzv#Cl>JwJ23$0`n2K6gpTfsKj@yL0(TJ`69fnVr{C3jm;-5U6LLq00mXaeV_M6Y~n(c+^_ zU;ubYXb^bLaFX*HU^tfbOO$`>C&3e}$=IJ@kaj=&2bBS2X5zLYAgG^OQIT$}U&197 zV-POgL2q@FFh#C^RzjCp*T1a;;GAkc5M@3{#QEAw#(Qt2C*Vs(dMMb`{kiYw0jF}3 z0bMvFIdLCjKh%8)ZK#uXe4tA7mW1wnrlDWr?)+GsNWsKqab1%<(I_0m>N!o`hxGbk31lhSy5~soxcE7dYTIJZ@3p zc}ri0ig)b^>#M3QvBei3?UH!Bns1ba<=@r-<7ZGz z+S+?C@Zp|cJRS|PO<{04jBcugBrh(|D1re*ixXt@=fl&?1AI?6r+6_s2%0Up>WWIT zn(6*wxrPjo2^%%nT1LO>2WG6o_b$+dV`}bi6=D)nN(P6e@WWIS)s;Xxv)Q zjdd$V5yZ;|2#jtoT0qGkBq5>7j6jj6OAKOLQ*Z9K76oROl z5zc$bI~z04I~GYkyf$w#AG?!niI@wm;c-naV(1ZE-^`pvpc*lYDZ)m~b53Rpw-Cc^ z>{t)Z2zDsGHhrk0*efBL{^ssw71ZhS5Rl3)HLD|6ANPs8L_w{57I4c)E zptgs&)~&L^kipPy3eXaI?JFWG9@2sL zoRs=X$jt?({j~6*!7aq0%)orwh*oHB&*kKq=&l9Fm>UOT{Kv=9I`4j-;u#}Pn>Cl+ zVdz7nrTQ=*!7$R?BdJ~j;(%J_`j010WmM9*b~sL6v81DCn#;~dpx4N-^ig{-q;3s2 zjxZLrx0*|SQC&8O8H1qVau&=-gYaxu@b8(d?SS?I{x%k5|I1kLe|Iha;&V^M)WOBn z*7(25YaR?(QmT)8qYIi#6BYHJPS-|3u?6^$ud7Bw?%W@4*4<&QCA=Qa z4|Vx-1qSv-{cZ&~&n10r3PO!ugtj}Zs-2)>`FUc8{>6{_Sl=)e$$720h!l%}3f9y^ z`YN{bb!x<@q8n<4g1X~OIw*+G;SJ(>(>=bm_-D!=r=udbmht2kDfjV!slR$WKGws>&zVue{h#>VY{;TjDI?FG(Qu6-N;m?Mx6bqh}Qm}srBYe6n; ziF`a-T&VH!P8J@Qf;j!TZG>il?hLYa<-HJfIx5HK(>J3SesohTnfec{!Zew|?tU&@iLh40Ih1)~6`b6nPLJy@lGvyN&x73hwFxb;)jbb*+S=Tu zgaoH87AsPD-V3Rs${Y$b@4U>yf|A3yt8L*}B=mm8oVa-J-p9i(M>r}iF}@@|V3fGm zj78(E$drYD-Rw-*Ll1$5Beq@I)4^|@@e6#Q85^y8o5HMRb%n!{B8Veyfe`FiR+l`h zM0I>-wis2w>~M2ajs^>4^3@1*B^njDkih3I*>jXZl;%=Y5G*zqCo~d`kYY$#5w!YG zMg5|AZC@zD)bsVx@>H+x>O@h(iJ~oAGm}J!r<&@@@v$?uxN$5j>0XsShDCp-$&CCJM0C-oNMTmvSLe{ByI7I@ zE6V3gTw4O`0_THz>v!q=&p>dS`-vAHGrN7)gYG+T#|;ry@vKTw`^=>n2JEbz`Wg!a zlED>sBT?T%i_0|n!6UAD`WoI!4=l{%y8}Pq$^M-I;{=j6shM`<;?RK^+GrrcJ9c>!ahE< zhoiAbQlh>S@2b98qO(R}=qA}Ju6y#$$zX1ZwRpbCY+_5Zoea{W?4?Yl@MPnB6lA)+ z^GA~s9-}w9Ginh!lDr{gMo$noJ2w|Q?aw)`RF$A0l{zr_@gVLH{0w>8pU#dSu zjJoK@eJ*d^5?%g;do^aHcfPT8hOl3C6JMKaPoCOzV(>1v--e$JTI{Lfw}b| z->2Mpv`(ao=e9&4a8e0YqjS0GwR*wz{(d)dYj(niSIU#-*JX8R)^FMqKch`IZ0|&x z&}dRM^KUl8oPb)G7h)RW+uu2Bg|{V<595G5r;HEI*ps`NdV%Xt+r_D7TADmNi3v9r zyzM|;BhrF$GwHo$abv@dS{;o@IADgqG0|kk`r0ZFRZ%#~#?B1E#>N=O?czN}JQXTi za3syD_I8VYhX)6DO!8^fmbvz!fDLEXb5yWXxm^)s9x4>&TmwOyAB*qG$SqqwJp>Nx zYh=!2Q`?<9j7u2BXH*2pf^aaBUXjIH@4X$gzQwEakc2W|?{KGsCgQW3SCGMY&Fe8m z=@W_?|N864a5wB|roo!vmFI=&KuY2HEo7pGhT}$YRlKbCtD9U`7!DG%lC{g*HNBV;Sqizz|wkJaB5xw5v6=5hd710oUB zX?SwvkD}ez{t@QcO4_RN8n$yv2;IFqwhc>$IgU9yf!6VPMu_kkS)uN`BoVa~(r^o8 zv;ONseG8V&iX}bPHAA`Hfk0rARZ*BDQ-Yx-d24ehnsX=#Z`f3jqs%on{0kFAs`LPN;1wGD;6r@ zVmm-FJpf?MvKtlLG8)GUIN}hA9_Z=jvq}jzVw;y%wC2K3r_2WwJW}RU7id$}Yocc} zjp-(4$T`3>OLIUr+;v;>mma0SQAT%}bu_j=?8t3RK7E>P2#j=UW+Nph0G;v+0(y2mlq2JxF13%>_*a-s7PVpoO)UnZc!aa@jfHb-)!W=;P(?i0hXpN2H*l=$$>G)&VPK~*F?w*^7Py2A8E0^0hQo=g zaZ$c!Xu-WtNb>tcpmz*ytqU|xO8qzm$c3Duetbe&+g zCgtt7&e?Wx%T-PtwBVh=_3U82fYeD>2FlJtj>y=xZ4;&JomjAaXT+=*;W6xcyOj;} z=#VMjxPUz%UGEq1Et3<0#qPVADJK$B_9FqFD{|uJ{3IX!d*TLnL2+JUGD46Ug#=7w z$s58%l=qNVk+)=n)uiw15ub=`n-6Ln(zBWWx7R!r+b|Ma2!WCB;X)A7+lfw~hunva z0&$9I*`RdeLCEbZ$IG&KAg|J0`fQiraStFSGP{{FNHA#2lb5dyn~80Z8R-d4#Dj(8 zwCX>i)#|t|TGg942}Z@F;Tp(QFHajBONMH#YrZ7Z52@9rq_w%1=}_0wYg6Z%$Ydt9 z#f7`cUJQvP?j}U8ju(r#57BY&qT@A0Q^pa=5i_O4d7!0X&^#n zBSkgj^#2UQ48qbvfP7oF8ndVb8qG~hS+z@Tg}zH9q_`^id{;s~gUxpEEo!jk;-c;I91bKq6sbFR(b z$Zp?!b3nvF$5318qJdcJ7s4Y1M7eAAh}3S4Ywm%Oj@_`d#Z#g=!|~sxwyP9RAt)Q= zE?_n6T@I>V^i}%|*Tn?#bOO;@y^mP?TKsVVD4oF(G>5AqA96!~dlKl0_w)2fUsdH< zc0=#%23lUi&X{yRv%DU?igareT!O*@d`T&^;RjuH)6rxVcY^Z5LIpOR_<2h)H%s9K zx)u-ZfA-fEcxdA*1aN67X%l}O(SoQK>KjnAz!)&)k$rr!UK@}^InA3kzn*twpKFlw z@wP|*ja%Or#T{|*pHx-)Eoqe6PaXjh&oymcKy-5SpMMMxKTlG zcYLluxJ8QPQBF*x`D#_cuM+%7K?pSFvu}6NKNEconr9*F*gGuFxEudz zv#}3lQePEeZiN-RoAp%g8JU~i7d)e#K%$^mvbP*AtW0FamrzJtF3TiefgWj?^RjGw zfwq&ef|h|07GqEn%wmDJ2a-P(5(Gad=a;mVdZ2N_w6^Oa6`TMHlb~XaM)4c$il!P> zsEv!*k`}inZCuOdx4dNL9|QZ|fXtO_En zg|n3@M$Nl(U7o!XbTKiP5%pb@Xn$c#zYMb*6^E1#wpG}xCm=d!%y!IX;rad8?i&_L z(;*bT7+WrcyTdX|S9xp#VxNfslJhm7=^{CXK-so_h#9naD-{HW5ZymC7S{jge;d_` zg=H#1mjOjrrb=de`|!i(^1OYO*ui!3Tx0CuI?7%!#@UIafP+7fa!Qfras}vVt?c+E zxtHQ@TJ=kj2J%Ld@=C2_y9zOSpOGu5?fM9COPQeDqFRKpT7Fdf`Y|w_yu;i!!BSaK zsgG02XnM0GZ7u#M`Gr`>*Ez)FEd(-!`CTL$s&K}(4D!&x-M41E6fkm#9zlmrNDw8$ zjUC3qgoF`gCe_Uq1c*vetY^}@kDiM$$ZO#+0oZ)8TIS;M=G;ABkLz|5+44#Tbg)Wp zdBM(~76#ci|0;~)mvb;plYrhS#E(j6VX~#go=gaIfTF=>%vo4-o~l^Cu1$n5@ywv1 zkd(gG$p{U|mltZQc5HG~i4zTcVy5{*S0h$RXqEt<;Juef-bP#^Qc5!!7hgJ@$q|Syoe%1 zJ|+gcQbPjIo4ylB3x7-ubaiK2Ko4U0+u3SmWC9L*FMZVlpXPQ(q#d7@_9}x6akv4T zIVx<%Cvn;@9ZI@)d$%229e2NOJ9^x3X}rx8C)b^)7&zM*8}IrJ+Y}n_FrsGP9MJ|P zrdLXJ43uLlS$(twlZ{UUktsfPK{#A+5V5m8 zgI92De>1zl%%;pVL0lg*O}<&bl3)4g?4^&r{pjkY|37)bT6{3!*@#5o>GXDb`0dv8 zySbtPQLK{O$6CXy&mqOf#{Sk_-#o^CW2e5EP=~CKQDP#D54=FLv?ItAv81%m_s|0CJ}0G6V4`YMO(J0-Rdl%RF)Q@1PSY``Vw zUWxH3)t|dtnvx8#nUJ`acI`db0o$>7@3$&h2ZVTLLAt+5PVdD-(J?6+=$t&Hm2l1meVt9t7ctqdN5Ac45EqPuRck3zsm?P_kNiE3RhU5IP14j~) zE690_fhz*VY|1x^^*kseKsJ$8ZcnYBdk4y}(Md{#=3|IOL3f@c72;~6%Hb+aVvS1L zNLlot84j)6xp$OUxAhGcLrfu&6IC##7lYs-b%8!S$o(dKT-Y@J@psAv}Sp->EDpwjU-%?&uhh$0!5`6;MD}q-5gdH}ybYD{2>q=S^Rh9~AVaJLP?ytnCi0 zha~hN^`Tx@CU3pNC{eb(e15&)9uDfEM3A092Yr~a>bZFvWy?SHLmcH?VEn#VOsqDi zc-nn2Zd{nsINQv&{M9jVhW>4D)KBkioM9zOMA0)ojkTJ@r(;7T3Hzn?Wro^v7l||7 zcP3@svAzpZ@(e7RTo}4;8R2_QqOECDEhqBEPVCNDb*{ym_rcQeFUFI40ydpb99}p` zVZT-+X&&3^f2Q<8sDZT#(<6h8;sOvJoiEx9_p?!hWKX4vU+)RO)_%Km?ai?TcOcm= z)yOr5QE}~L@Ro<7tj)7|wR|1%^g;HArBi6F^V?ibZ*F(0d;x!-WAL`CJpjc9 z0Wq$7_dy5>1_1we8w9;w^!L}R(EGu^-!2Fe1oUs)1pN*7kBx%g|W03!XPRIHqr9%JOd*Z)EU$QTS&;_zyzFH}Ja<@lWvkJl3Dnh^T)_tby1c;D0Nadc*#!;_&Ch y8Q?Eib@@NA|7k|@-;n>TE`Ke new generalPurposeRegister()); + + // I/O Controller: Manages data transfer and communication + this.ioController = { + busy: false, // Indicates if an I/O operation is in progress + sequencerSignal: null, // Signal from sequencer + ioInterfaceSignal: null // Signal from I/O interface + }; } - getBuffer() { - return this.buffer; + writeToBuffer(registerIndex, value) { + if (registerIndex < 0 || registerIndex >= 4) { + throw new Error("Invalid register index"); + } + this.buffer[registerIndex].setvalue(value); + this.ioController.busy = true; } - setBuffer(buffer) { - this.buffer = buffer; + + + readFromBuffer(registerIndex) { + if (registerIndex < 0 || registerIndex >= 4) { + throw new Error("Invalid register index"); + } + return this.buffer[registerIndex].getvalue(); } - write() { + displayValue() { + console.log("I/O Buffer Contents:"); + this.buffer.forEach((reg, index) => { + console.log(`Register ${index}: ${reg.getvalue()}`); + }); } } -export default IOUnit; \ No newline at end of file + +export default IOUnit; diff --git a/src/Emulator/Instruction.js b/src/Emulator/Instruction.js index 407819b..ca93993 100644 --- a/src/Emulator/Instruction.js +++ b/src/Emulator/Instruction.js @@ -1,11 +1,74 @@ -import { Registers, memory, Alu1, IP ,queue } from "../pages/Ide"; +import { Registers, memory, Alu1, IP ,queue } from "../pages/Ide/index.jsx"; import { TwosComplement } from "./ALU.js"; import { gsap } from "gsap"; +import IOUnit from "./IO_Unit.js"; +import { Register } from "./Register.js"; // import { Register } from "./Register.js"; //////////////////////////////////////////////// function Dec2bin(dec){ return ("00000000" + (parseInt(dec, 10)).toString(2)).substr(-8); } +function binaryToDecimalNumber(binaryStr) { + return parseInt(binaryStr, 2); +} +// Ensure receiveWriteValue is globally accessible +// Ensure receiveWriteValue is globally accessible +function showWritePopup() { + return new Promise((resolve) => { + let popup = window.open("", "Write to Register", "width=400,height=300"); + + popup.document.write(` +

Write to Register

+ + + + + + `); + + // Store resolve function globally so it can return the value to the main window + window.resolveWriteValue = (value) => { + console.log("🟢 Received input from user:", value); + resolve(parseInt(value, 10) || 0); // Convert input to number (default 0 if empty) + }; + }); +} + + + + +window.receiveWriteValue = function(value) { + console.log("✅ Main Window: Received value from pop-up:", value); + + const ioUnit = memory.ioUnit; + + if (!isNaN(value)) { + value = parseInt(value, 10); + ioUnit.writeToBuffer(0, value); + console.log(`✅ Stored ${value} in I/O buffer register 0.`); + + // Resume instruction execution + if (typeof window.writeCallback === "function") { + console.log("🟢 Resuming instruction after user input..."); + window.writeCallback(); + window.writeCallback = null; // Clear the callback after execution + } + } else { + console.log("❌ Invalid input. Please enter a number."); + } +}; + + /////////////////animations to test//////////////////// const IounitToBus={ @@ -18,6 +81,22 @@ const IounitToBus={ gsap.to(".ball",{opacity:"0" ,duration:1,delay:2}); }, } +const BusToIO = { + value: "", + target: ".ball", + time: 3000, + anim: (val, h, w) => { + gsap.fromTo(".ball", + { height: "2.812%", width: "1.4%", borderRadius: "50%", x: w * 0.221, y: h * 0.46, opacity: "0" }, + { opacity: "1", duration: 1 } + ); + gsap.fromTo(".ball", + { x: w * 0.221, y: h * 0.46 }, + { y: h * 0.39, duration: 1, delay: 1 } // Moves upward, opposite of IOTOBUS + ); + gsap.to(".ball", { opacity: "0", duration: 1, delay: 2 }); + }, +}; const BusToRual1={ value:"", @@ -4359,5 +4438,140 @@ class InstructionPOPA{ this.buildanim=function(){} } } +class InstructionREAD { + constructor() { + this.value1 = 0; + this.value2 = 0; + this.addresse1 = 0; + this.register1 = 0; + this.addresse2 = 0; + this.register2 = 0; + this.taille = 0; + this.stepsNum = 1; + this.name = "READ"; + + this.steps = [ + () => { + const ioUnit = memory.ioUnit; // Access I/O Unit + + if (!ioUnit.ioController.busy) { + ioUnit.ioController.busy = true; // Mark I/O as busy + + let value = this.value1; // Read from CPU register (e.g., R1) + ioUnit.writeToBuffer(0, value); + let popup = window.open("", "Buffer Contents", "width=400,height=300"); + popup.document.write(`

Buffer Contents

${ioUnit.readFromBuffer(0)}

`); + // alert("Buffer Contents: " + ioUnit.readFromBuffer(0));// Store in I/O buffer register 0 + + console.log(`CPU to IO: Moved data ${value} from CPU register R${this.register1} to I/O buffer.`); + ioUnit.displayValue(); + ioUnit.ioController.busy = false; + } else { + console.log("I/O Unit busy, READ delayed"); + return false; // Delay execution if busy + } + }, + ]; + this.buildanim = function () { + return [ + { + value: "READ", + target: addanim.target, + time: addanim.time, + anim: addanim.anim, + }, + { + value: this.value1, + target: RegistersToBus.target, + time: RegistersToBus.time, + anim: RegistersToBus.anim, + }, + { + value: this.value1, + target: BusToIO.target, + time: BusToIO.time, + anim: BusToIO.anim, + }, + + + ]; + }; + } +} + +class InstructionWRITE { + constructor() { + this.value1 = 0; + this.value2 = 0; + this.addresse1 = 0; + this.register1 = 0; + this.addresse2 = 0; + this.register2 = 0; + this.taille = 0; + this.stepsNum = 1; + this.name = "WRITE"; + + this.steps = [ + async () => { + const ioUnit = memory.ioUnit; + + if (!ioUnit.ioController.busy) { + ioUnit.ioController.busy = true; + + console.log("🟢 InstructionWRITE: Waiting for user input..."); + + // Wait for user input asynchronously before proceeding + const value = await showWritePopup(); + + ioUnit.writeToBuffer(0, value); + console.log(`✅ User input received: ${value}. Stored in I/O buffer register 0.`); + + // Resume execution + this.resume(); + } else { + console.log("🔴 InstructionWRITE: I/O Unit busy, WRITE delayed"); + return false; + } + } + ]; + + // Animation sequence + this.buildanim = function () { + const ioUnit = memory.ioUnit; + return [ + { + value: "WRITE", + target: addanim.target, + time: addanim.time, + anim: addanim.anim, + }, + { + value: ioUnit.readFromBuffer(0), + target: IounitToBus.target, + time: IounitToBus.time, + anim: IounitToBus.anim, + }, + { + value: ioUnit.readFromBuffer(0), + target: BusToRegisters.target, + time: BusToRegisters.time, + anim: BusToRegisters.anim, + }, + ]; + }; + } + + resume() { + const ioUnit = memory.ioUnit; + + let value = ioUnit.readFromBuffer(0); + let register = parseInt(this.register1, 2); + Registers[register].setvalue(TwosComplement(value, 16)); + + ioUnit.ioController.busy = false; + console.log(`✅ IO to CPU: Moved data ${value} from I/O buffer to CPU register R${register}.`); + } +} + -export {InstructionADD,InstructionMOV00,InstructionMOV01,InstructionMOV10,InstructionMOV11,InstructionSUB,InstructionMUL,InstructionDIV,InstructionBSE,InstructionBIE,InstructionBI,InstructionBS,InstructionBNE,InstructionBE,InstructionBR,InstructionPOP,InstructionPUSH,InstructionAND,InstructionOR,InstructionNAND,InstructionNOR,InstructionXOR,InstructionNEG,InstructionNOT,InstructionROL,InstructionROR,InstructionSHL,InstructionSHR,InstructionPOPA,InstructionPUSHA} +export {InstructionADD,InstructionMOV00,InstructionMOV01,InstructionMOV10,InstructionMOV11,InstructionSUB,InstructionMUL,InstructionDIV,InstructionBSE,InstructionBIE,InstructionBI,InstructionBS,InstructionBNE,InstructionBE,InstructionBR,InstructionPOP,InstructionPUSH,InstructionAND,InstructionOR,InstructionNAND,InstructionNOR,InstructionXOR,InstructionNEG,InstructionNOT,InstructionROL,InstructionROR,InstructionSHL,InstructionSHR,InstructionPOPA,InstructionPUSHA,InstructionREAD, InstructionWRITE} \ No newline at end of file diff --git a/src/Emulator/MC.js b/src/Emulator/MC.js index fbb09a1..1fbf6a9 100644 --- a/src/Emulator/MC.js +++ b/src/Emulator/MC.js @@ -1,50 +1,69 @@ /* eslint-disable eqeqeq */ -import { Register } from "./Register.js" +import { Register } from "./Register.js"; +import IOUnit from "./IO_Unit.js"; // 🔥 Import IOUnit + class MC { - constructor(){ - this.rim=new Register() - this.ram=new Register() - this.stack = new Array(100)//size à revoir - this.data = new Array (100) - this.code = new Array(100) + constructor() { + this.rim = new Register(); + this.ram = new Register(); + this.mar = new Register(); + this.stack = new Array(100); // size à revoir + this.data = new Array(100); + this.code = new Array(100); + this.ioUnit = new IOUnit(); // ✅ Add IOUnit instance } - setcode(code){ - this.code=code; + + setcode(code) { + this.code = code; } - setRim (val){//val in hexa - this.rim=val; + + setRim(val) { // val in hexa + this.rim = val; } - setRam (adr){//val in decimal - this.ram=adr; + + setRam(adr) { // val in decimal + this.ram = adr; } - getRam(){ - return this.ram; + + getRam() { + return this.ram; } - getRim (){ - return this.rim + + getRim() { + return this.rim; } - read(iscode){ - if(iscode==true){ - this.rim=this.code[parseInt(this.ram,2)] + + read(iscode) { + if (iscode == true) { + this.rim = this.code[parseInt(this.ram, 2)]; + } else { + this.rim = this.data[parseInt(this.ram, 2)]; + } } - else{ - this.rim=this.data[parseInt(this.ram,2)] + + write() { + this.data[parseInt(this.ram, 2)] = this.rim; } + + popval() { + this.rim = this.stack.pop(); } - write(){ - this.data[parseInt(this.ram,2)]=this.rim; + + pushval() { + this.stack.push(this.rim); } - popval(){ - this.rim=this.stack.pop(); - } - pushval(){ - this.stack.push(this.rim); - } - getData(){ + + getData() { return this.data; } - getstack(){ + + getstack() { return this.stack; } + + getIOUnit() { // ✅ Helper method to get IOUnit + return this.ioUnit; + } } -export default MC; \ No newline at end of file + +export default MC; diff --git a/src/Emulator/Opcodes.js b/src/Emulator/Opcodes.js index 0227590..0a08928 100644 --- a/src/Emulator/Opcodes.js +++ b/src/Emulator/Opcodes.js @@ -1,4 +1,4 @@ -import { InstructionADD,InstructionMOV00,InstructionMOV01,InstructionMOV10,InstructionMOV11,InstructionSUB,InstructionMUL,InstructionDIV, InstructionPUSH, InstructionBR, InstructionNOR, InstructionNEG, InstructionROR, InstructionROL, InstructionSHL, InstructionSHR, InstructionBE, InstructionBS, InstructionBSE, InstructionBI, InstructionBIE, InstructionBNE, InstructionNOT, InstructionOR, InstructionAND, InstructionNAND, InstructionXOR } from "./Instruction.js"; +import { InstructionADD,InstructionMOV00,InstructionMOV01,InstructionMOV10,InstructionMOV11,InstructionSUB,InstructionMUL,InstructionDIV, InstructionPUSH, InstructionBR, InstructionNOR, InstructionNEG, InstructionROR, InstructionROL, InstructionSHL, InstructionSHR, InstructionBE, InstructionBS, InstructionBSE, InstructionBI, InstructionBIE, InstructionBNE, InstructionNOT, InstructionOR, InstructionAND, InstructionNAND, InstructionXOR, InstructionREAD, InstructionWRITE } from "./Instruction.js"; function hash(key){ if(key=="0000000"){ @@ -55,7 +55,12 @@ function hash(key){ return 25; }else if(key=="0000110"){//XOR return 26; + } else if(key=="1000"){ // Opcode for READ + return 27; + } else if(key=="1001"){ // Opcode for WRITE + return 28; } + } let ADDinst=new InstructionADD(); let MOV00inst=new InstructionMOV00(); @@ -84,6 +89,8 @@ let ORinst = new InstructionOR(); let ANDinst = new InstructionAND(); let NANDinst = new InstructionNAND(); let XORinst = new InstructionXOR(); +let READinst = new InstructionREAD(); +let WRITEinst = new InstructionWRITE(); let hashmap=[{ key:"00", instrObject:ADDinst, @@ -192,5 +199,13 @@ let hashmap=[{ key:"0c", instrObject:XORinst, }, +{ + key:"8", + instrObject:READinst +}, +{ + key:"9", + instrObject:WRITEinst +} ]; -export {hash,hashmap}; \ No newline at end of file +export {hash,hashmap}; diff --git a/src/Emulator/Queue.js b/src/Emulator/Queue.js index 0cd9bbf..5ef8dbd 100644 --- a/src/Emulator/Queue.js +++ b/src/Emulator/Queue.js @@ -1,4 +1,4 @@ -import { memory,IP } from "../pages/Ide"; +import { memory,IP } from "../pages/Ide/index.jsx"; import { TwosComplement } from "./ALU.js"; import { gsap } from "gsap"; diff --git a/src/Emulator/Sequencer.js b/src/Emulator/Sequencer.js index 5c1d4f9..5d8c078 100644 --- a/src/Emulator/Sequencer.js +++ b/src/Emulator/Sequencer.js @@ -1,5 +1,5 @@ import { Register } from "./Register.js"; -import { queue, Registers, addressingModes } from "../pages/Ide"; +import { queue, Registers, addressingModes } from "../pages/Ide/index.jsx"; import { hash, hashmap } from "./Opcodes.js"; import { gsap } from "gsap"; // import Console from "../Console.jsx";____conflict!!!!!!!!!! diff --git a/src/codemirror/mode/myLang/assembly.js b/src/codemirror/mode/myLang/assembly.js index 526754e..6b30980 100644 --- a/src/codemirror/mode/myLang/assembly.js +++ b/src/codemirror/mode/myLang/assembly.js @@ -1,5 +1,5 @@ import define from 'requirejs' -import CodeMirror from 'codemirror' +import CodeMirror from 'codemirror' (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -14,11 +14,18 @@ import CodeMirror from 'codemirror' })(function(CodeMirror) { CodeMirror.defineMode("8086", function(config, parserConfig) { - var keywords = ["mov", "add", "sub", "mul", "div", "jmp", "call", "ret", "push", "pop", "label", "bri", "be", "bne", "bs", "bi", "bse", "bie", "ror", "rol", "shr", "shl"]; - var registers = ["r1", "r2", "r3", "r4", "idr", "br", "sr", "acc", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h", "accl", "acch"]; + var keywords = ["mov", "add", "sub", "mul", "div", "jmp", "call", "ret", "push", "pop", + "label", "bri", "be", "bne", "bs", "bi", "bse", "bie", "ror", "rol", + "shr", "shl", "read", "write"]; // Added "read" and "write" + + var registers = ["r1", "r2", "r3", "r4", "idr", "br", "sr", "acc", "r1l", "r1h", "r2l", + "r2h", "r3l", "r3h", "accl", "acch"]; + var number = /-?(?:0x[0-9a-f]+|\d+)/i; + function tokenBase(stream, state) { var ch = stream.next(); + if (ch === "/") { if (stream.eat("")) { state.tokenize = tokenComment; @@ -29,69 +36,68 @@ import CodeMirror from 'codemirror' return "comment"; } } + if (ch === ";" || ch === "#") { stream.skipToEnd(); return "comment"; } + if (/[a-zA-Z_]/.test(ch)) { stream.eatWhile(/[\w.]/); var cur = stream.current().toLowerCase(); - if (keywords.indexOf(cur) >= 0) { - return "key"; - } - if (registers.indexOf(cur) >= 0) { - return "reg"; - } - + if (keywords.indexOf(cur) >= 0) { + return "key"; // READ & WRITE will now be highlighted as instructions + } + if (registers.indexOf(cur) >= 0) { + return "reg"; } - if (/\d/.test(ch)) { + } + + if (/\d/.test(ch)) { stream.match(number); return "num"; - } + } if(/[@*]/.test(ch)){ return "opadr"; } if(/[[]]/.test(ch)){ - return "opadr" + return "opadr"; } + return null; + } - return null; - } - - function tokenComment(stream, state) { - let maybeEnd = false, ch; + function tokenComment(stream, state) { + let maybeEnd = false, ch; - while ((ch = stream.next())) { - if (ch === "/" && maybeEnd) { - state.tokenize = null; - break; + while ((ch = stream.next())) { + if (ch === "/" && maybeEnd) { + state.tokenize = null; + break; + } + maybeEnd = ch === ""; } - maybeEnd = ch === ""; + return "comment"; } - return "comment"; - } - - return { - startState: function() { - return { - tokenize: null, - }; - }, + return { + startState: function() { + return { + tokenize: null, + }; + }, - token: function(stream, state) { - if (state.tokenize) { - return state.tokenize(stream, state); - } - - return tokenBase(stream, state); - }, - }; + token: function(stream, state) { + if (state.tokenize) { + return state.tokenize(stream, state); + } + return tokenBase(stream, state); + }, + }; }); -}); \ No newline at end of file +}); diff --git a/src/pages/Ide/index.jsx b/src/pages/Ide/index.jsx index cdd9857..e4d98d8 100644 --- a/src/pages/Ide/index.jsx +++ b/src/pages/Ide/index.jsx @@ -5,7 +5,7 @@ import UAParser from 'ua-parser-js'; import "./style.css" ///// import components ////// -import { NavBar, HelpSection, SaveCodeButton } from "../../components" +import { NavBar, HelpSection, SaveCodeButton } from "../../components/index.js" ////// import machine components ////// @@ -24,10 +24,10 @@ import "../../codemirror/theme/material.css"; import "../../codemirror/mode/myLang/assembly.js" /////import assembler modules////////// -import { Assembler } from "../../assembler/Assembler"; -import {helpDescription} from "../../Constants/HelpDescription"; -import {HexaToCode} from "../../HexaToCode/HexaToCode" -import { Errorcalm } from "../../assembler/Errorcalm"; +import { Assembler } from "../../assembler/Assembler.js"; +import {helpDescription} from "../../Constants/HelpDescription.js"; +import {HexaToCode} from "../../HexaToCode/HexaToCode.js" +import { Errorcalm } from "../../assembler/Errorcalm.js"; import { useLocation } from 'react-router-dom'; import { useEffect } from 'react'; @@ -338,20 +338,25 @@ const Ide = ({currentUser})=>{ if(iscode){ console.log(handleStoreCode) inputouter=Assembler.assemblecode(handleStoreCode()) + }else{ inputouter=handleStoreCode(); } let input=convertStrings(inputouter); input.push("ff"); + console.log("this is :"+ input) try { - + console.log("hachmi"); if (Errorcalm.errorr === 0) { + console.log("drsas") traitement(input); - + }else{ + console.log("SIks") setresult(Errorcalm.printError()); + seterr(true); } From 31e63d06f3f0f4f235caa64c9c37a39ab5005607 Mon Sep 17 00:00:00 2001 From: redouane-bensaci Date: Fri, 18 Apr 2025 09:29:24 +0100 Subject: [PATCH 08/12] merged v1 --- src/Emulator/IO_Unit.js | 81 +++++++---- src/Emulator/Sequencer.js | 1 + src/assembler/Assembler.js | 38 +++-- src/assembler/Errorcalm.js | 3 + src/assembler/SemanticAnalysis.js | 10 +- src/assembler/preprocessing.js | 230 +++++++++++++++++------------- src/pages/Arch/index.jsx | 5 +- src/pages/Ide/index.jsx | 23 ++- 8 files changed, 225 insertions(+), 166 deletions(-) diff --git a/src/Emulator/IO_Unit.js b/src/Emulator/IO_Unit.js index 377bfef..8ab7a99 100644 --- a/src/Emulator/IO_Unit.js +++ b/src/Emulator/IO_Unit.js @@ -2,37 +2,62 @@ import { generalPurposeRegister } from "./Register.js"; class IOUnit { constructor() { - // Buffer: 4 registers, each holding 2 bytes (total 8 bytes) - this.buffer = new Array(4).fill(null).map(() => new generalPurposeRegister()); - - // I/O Controller: Manages data transfer and communication - this.ioController = { - busy: false, // Indicates if an I/O operation is in progress - sequencerSignal: null, // Signal from sequencer - ioInterfaceSignal: null // Signal from I/O interface - }; + // Buffer with 50 slots, initially empty + this.buffer = new Array(50).fill(null).map(() => ({ value: null, filled: false })); + + this.ioController = { + status: "idle", + transferInProgress: false, + }; } - writeToBuffer(registerIndex, value) { - if (registerIndex < 0 || registerIndex >= 4) { - throw new Error("Invalid register index"); - } - this.buffer[registerIndex].setvalue(value); - this.ioController.busy = true; + + // Write data into the buffer + writeToBuffer(index, value) { + if (index < 0 || index >= this.buffer.length) { + console.error(`Invalid index: ${index}. Must be between 0 and ${this.buffer.length - 1}`); + return; + } + + this.buffer[index].value = value; + this.buffer[index].filled = true; + + console.log(`Value "${value}" written to buffer slot ${index}`); } - - - readFromBuffer(registerIndex) { - if (registerIndex < 0 || registerIndex >= 4) { - throw new Error("Invalid register index"); - } - return this.buffer[registerIndex].getvalue(); + + // Read data while ignoring truly empty slots + readFromBuffer() { + const bufferString = this.buffer + .filter(slot => slot.filled) // Keep only filled slots + .map(slot => slot.value) // Extract values + .join(""); + + console.log(`Buffer content (excluding empty columns): "${bufferString}"`); + return bufferString; + } + convertCharToASCII(index) { + if (index >= 0 && index < this.buffer.length) { + const asciiValue = this.buffer[index].toString().charCodeAt(0) || 0; + console.log(`Character at index ${index}: ${this.buffer[index]}, ASCII: ${asciiValue}`); + return asciiValue; + } else { + console.error("Index out of bounds"); + return null; } - displayValue() { - console.log("I/O Buffer Contents:"); - this.buffer.forEach((reg, index) => { - console.log(`Register ${index}: ${reg.getvalue()}`); - }); + } + writeASCIIToBuffer(asciiValue, index) { + if (index >= 0 && index < this.buffer.length) { + this.buffer[index] = String.fromCharCode(asciiValue); + console.log(`Stored character '${this.buffer[index]}' at index ${index} from ASCII ${asciiValue}`); + } else { + console.error("Index out of bounds"); } + } + emptyBuffer() { + this.buffer.forEach(slot => { + slot.value = 0; // Reset value to 0 + slot.filled = false; // Mark as empty + }); + +} } - export default IOUnit; diff --git a/src/Emulator/Sequencer.js b/src/Emulator/Sequencer.js index 5d8c078..d9b3959 100644 --- a/src/Emulator/Sequencer.js +++ b/src/Emulator/Sequencer.js @@ -1,3 +1,4 @@ +/* eslint-disable no-unused-vars */ import { Register } from "./Register.js"; import { queue, Registers, addressingModes } from "../pages/Ide/index.jsx"; import { hash, hashmap } from "./Opcodes.js"; diff --git a/src/assembler/Assembler.js b/src/assembler/Assembler.js index a56cdae..c00f319 100644 --- a/src/assembler/Assembler.js +++ b/src/assembler/Assembler.js @@ -10,6 +10,10 @@ import { Lexer } from './Lexer.js'; import {Errorcalm} from './Errorcalm.js' import {SemanticAnalysis} from './SemanticAnalysis.js' import { element } from 'prop-types'; +import { preprocessing } from './preprocessing.js'; +import MC from '../Emulator/MC.js'; +import { memory } from '../pages/Ide/index.jsx'; + export const FuncInterface ={ adrmap : (txt,size,dep)=>{ @@ -213,13 +217,13 @@ while (hexString.length < size) { labelobj = Assembler.Labellist.find(element => { return element.name === labelname; }); + console.log(labelname) if (labelobj == false) { //error Errorcalm.set_SemanticError(new Errorcalm("Label not found",null,linenumber)); return {type: 'ERROR', value: null}; }else{ - //return the address return {type: 'NUMBER', value: labelobj.address} }}, @@ -420,8 +424,6 @@ while (hexString.length < size) { } } - - export class Assembler{ static MAXNUM = 65535; @@ -436,13 +438,14 @@ export class Assembler{ constructor(input){ + let lexicalList = input.map((t,index)=> {return new Lexer(t,index).LexicalList} ) if (Errorcalm.LexicalError.length > 0) { Errorcalm.printError(); }else{ - this.input = lexicalList; + this.input = lexicalList this.toAssemble = new SemanticAnalysis(this.input); - let ret = FuncInterface.confirmationfunction(this.toAssemble.Semanticlist); + // let ret= functinterface.cofirmationfunction(this.input); } } @@ -849,26 +852,24 @@ export class Assembler{ } } } - static assemblecode(input){ + static assemblecode(input){ + + let input2 = preprocessing.preprocessor(input) + MC.data = Array(100).fill().map((_, i) => FuncInterface.binaryToHexoneByte(input2.data[i] ?? "00000000")) + console.log("MC.data:",MC.data) + Assembler.Labellist.push(...input2.varList) SemanticAnalysis.labeltype = true; - console.log("input: ",input) - let output = new Assembler(input) ; - console.log("output: ",output) + let output = new Assembler(input2.code); var assembledcode = []; var toassmb = (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"; - console.log("to assumb status: ",toassmb) var ipTrack = 0; var i=0; var lines=(Assembler.Labellist.length === 0 )?toassmb.length:Assembler.Labellist[i].linedeclared; - console.log("lines: ",lines) // deux pass first pass stays as it is with adding a delimater at each label and then re apply the semantic analysis for the labels and then reassemble the code if ( Errorcalm.SemanticError.length === 0 ) { for (let index = 0; index < toassmb.length; index++) { - console.log("index: ",index) - console.log("lines: ",lines) if (index >= lines) { - Assembler.Labellist[i].address = ipTrack - console.log("check labellist: ",Assembler.Labellist); + Assembler.Labellist[i].address = ipTrack; i++; if (i < Assembler.Labellist.length) { lines=Assembler.Labellist[i].linedeclared-Assembler.Labellist[i-1].linedeclared-1+index; @@ -876,18 +877,15 @@ export class Assembler{ lines=toassmb.length; } } - console.log("check labellist: ",Assembler.Labellist); ipTrack = ipTrack+(Assembler.assemble(toassmb[index]).length/2) } SemanticAnalysis.labeltype = false; - output = new Assembler(input) + output = new Assembler(input2.code) toassmb = (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"; - console.log("to assumb status: ",toassmb) for (let index = 0; index < toassmb.length; index++) { assembledcode.push(Assembler.assemble(toassmb[index])) } - console.log(assembledcode); - return assembledcode; + return {code: assembledcode, memory: memory.data}; // here put the return in case of success }else{ diff --git a/src/assembler/Errorcalm.js b/src/assembler/Errorcalm.js index a71e66c..9c6d48d 100644 --- a/src/assembler/Errorcalm.js +++ b/src/assembler/Errorcalm.js @@ -1,3 +1,6 @@ +/* eslint-disable no-useless-concat */ +/* eslint-disable no-unused-vars */ +/* eslint-disable eqeqeq */ import { Assembler,FuncInterface } from "./Assembler.js"; import { SemanticAnalysis } from "./SemanticAnalysis.js"; import { Lexer } from "./Lexer.js"; diff --git a/src/assembler/SemanticAnalysis.js b/src/assembler/SemanticAnalysis.js index e2c2e5d..46179e5 100644 --- a/src/assembler/SemanticAnalysis.js +++ b/src/assembler/SemanticAnalysis.js @@ -9,7 +9,6 @@ export class SemanticAnalysis { Semanticlist = [] static labeltype = true; constructor(input) { - let lexicalList = input; for(let i = 0; i < lexicalList.length; i++){ let firstword = lexicalList[i][0] @@ -18,7 +17,7 @@ export class SemanticAnalysis { if (lexicalList[i].length == 3) { if (lexicalList[i][2].type == 'NUMBER') { if( lexicalList[i][2].value < Assembler.MAXNUM){ - if(lexicalList[i][1].type == 'TEXT' ||lexicalList[i][1].type == 'TEXTT'){ + if(lexicalList[i][1].type == 'TEXT' || lexicalList[i][1].type == 'TEXTT'){ if(Lexer.isValidString(lexicalList[i][1].value)){ // filters for text standards and validity of the text // check if label already existing @@ -33,12 +32,12 @@ export class SemanticAnalysis { if (!found) { if (lexicalList[i][1].type === 'TEXTT') { if (SemanticAnalysis.labeltype){ - Assembler.Labellist.push({ name: labelname, address: lexicalList[i][2].value, linedeclared:i, label: true }) + Assembler.Labellist.push({ name: labelname, address: parseInt(lexicalList[i][2].value), linedeclared:i, label: true }) } } else { if (!SemanticAnalysis.labeltype){ - Assembler.Labellist.push({ name: labelname, address: lexicalList[i][2].value, linedeclared:i, label: false }) + Assembler.Labellist.push({ name: labelname, address: parseInt(lexicalList[i][2].value), linedeclared:i, label: false }) } } }else{ @@ -64,6 +63,7 @@ export class SemanticAnalysis { } } } + if (!SemanticAnalysis.labeltype){ for(let i = 0; i < lexicalList.length; i++){ // here operation with each line of code // we must check if it is a label or an instruction @@ -241,7 +241,7 @@ export class SemanticAnalysis { } - } + }} diff --git a/src/assembler/preprocessing.js b/src/assembler/preprocessing.js index 167081e..3c26c39 100644 --- a/src/assembler/preprocessing.js +++ b/src/assembler/preprocessing.js @@ -1,12 +1,14 @@ -const ErrorCalm = require("./assembler/Errorcalm.js") - -class preprocessing{ +/* eslint-disable no-loop-func */ +import { FuncInterface } from './Assembler.js' +import {Errorcalm} from './Errorcalm.js' +export class preprocessing{ //this should include all reserved words, or if there is a global object serving the same purpose static reservedWords = new Set(['R1', 'R2', 'R3', 'R4', 'ACC', 'BR', 'IDR', 'SR', 'R1R', 'R2R', 'R3R', 'ACCR', 'R1L', 'R2L', 'R3L', 'ACCL' , 'PUSHA', 'POPA', 'RET', 'NEG', 'NOT', 'SHL', 'SHR', 'READ', 'WRITE', 'PUSH', 'POP', 'ROR', 'ROL', 'CALL', 'BE', 'BNE', 'BS', 'BI', 'BIE', 'BSE', 'BRI' , 'NAND', 'CMP', 'MOV', 'ADD', 'SUB', 'MUL', 'DIV', 'AND', 'OR', 'XOR', 'NOR', 'MACRO', 'ENDM', 'START', 'END','SDATA', 'ENDS']) static macroKeyWords = ['MACRO', 'ENDM'] static DataKeyword = ['SDATA', 'ENDS'] + constructor(){ this.MACROS = [] this.macroKeyWord = new Set() @@ -31,7 +33,7 @@ class preprocessing{ } if(i === n){ //error segment not closed - this.errors.push(new ErrorCalm("Data segment not closed", "PREPROCESSING", i)) + this.errors.push(new Errorcalm("Data segment not closed", "PREPROCESSING", i)) return } this.dataSegment.push(code[i++]) @@ -59,28 +61,30 @@ class preprocessing{ // for example [X, db, 15] if(line.length < 3){ // throw error, wrong variable declaration - this.errors.push(new ErrorCalm("Wrong variable declaration", "PREPROCESSING", i)) + this.errors.push(new Errorcalm("Wrong variable declaration", "PREPROCESSING", i)) return } if(this.varList.includes(line[0])){ // throw error, variable already declared - this.errors.push(new ErrorCalm("Variable already declared", "PREPROCESSING", i)) + this.errors.push(new Errorcalm("Variable already declared", "PREPROCESSING", i)) return } if(!isNaN(Number(line[0][0]))){ // throw error, variable name cannot start with a number - this.errors.push(new ErrorCalm("Variable name cannot start with a number", "PREPROCESSING", i)) + this.errors.push(new Errorcalm("Variable name cannot start with a number", "PREPROCESSING", i)) return } let varHolder = {} // assign the name of the var to the corresponding object - varHolder.label = line[0] + varHolder.label = false + varHolder.linedeclared = i + varHolder.name = line[0] varHolder.address ??= curAddress this.varList.push(varHolder) if(!(['DB', 'DW']).includes(line[1])){ // throw error, wrong variable length declaration - this.errors.push(new ErrorCalm("Wrong variable type", "PREPROCESSING", i)) + this.errors.push(new Errorcalm("Wrong variable type", "PREPROCESSING", i)) return } let length = line[1] === 'DB' ? 0 : 1 // data on one byte or on two bytes if line[0] === 'DW' @@ -103,23 +107,29 @@ class preprocessing{ if(length === 1){ if(val <= Math.abs(Math.pow(2,16))){ // use 2s complement instead of this expression - val = val.toString(2).padStart(16, '0') + val = FuncInterface.decimalTobinByte(val,1) return [String(val).substring(0,Math.floor(val.length / 2)), String(val).substring(Math.floor(val.length / 2))] } else { - this.errors.push(new ErrorCalm("value out of bounds", "PREPROCESSING", index)) - return + this.errors.push(new Errorcalm("value out of bounds", "PREPROCESSING", index)) + return null } } else { if(val <= Math.abs(Math.pow(2,8))){ // use 2s complement instead of this expression - return val.toString(2).padStart(8, '0') + return FuncInterface.decimalTobinByte(val,0) } else { - this.errors.push(new ErrorCalm("value out of bounds", "PREPROCESSING", index)) - return + this.errors.push(new Errorcalm("value out of bounds", "PREPROCESSING", index)) + return null } } } else{ + if (val[0] !== '"' || val[val.length - 1] !== '"') { + // throw error, string not closed + this.errors.push(new Errorcalm("String must be unclosed within in a pair of \"\"", "PREPROCESSING", index)) + return null; + + } // we have a string I guess, we convert to ascii and we pad when we write binary string in the memory if(length === 0){ return val.split('').filter(char => char !== '"').map(char => char.charCodeAt(0).toString(2).padStart(8,'0')) @@ -135,31 +145,6 @@ class preprocessing{ console.log(this.varList) } - - // remove static from all methods below, cuz we are acting on objects - removeComments(code){ //removes comments from all code as well as empty lines - console.log(typeof(code)) - code = code.toUpperCase().split('\n') - - const output = [] - const n = code.length - - for(let i = 0; i < n; i++){ - let temp = code[i].split('//') - if(temp[0] === '' || temp[0].trim(' ','') === ''){ - continue - } - - if(temp.length === 1){ - - output.push(temp[0].trim()) - continue - } - - output.push(temp[0].trim()) - } - return output - } // we suppose the code is given to use as extractMacro(input /*it should be the whole code */){ // input is the whole code which we divided into an array of strings @@ -171,38 +156,38 @@ class preprocessing{ let line = input[curLine].match(/([a-zA-Z_][a-zA-Z0-9_]*|[,:])/g) if(line[0] === 'ENDM'){ // throw error, macro not declared - this.errors.push(new ErrorCalm("Macro not declared", "PREPROCESSING", curLine)) + this.errors.push(new Errorcalm("Macro not declared", "PREPROCESSING", curLine)) return } if(line[0] === 'MACRO'){ let macroClosed = false if(line.length < 2){ // throw error, no macro name provided - this.errors.push(new ErrorCalm("No macro name provided", "PREPROCESSING", curLine)) + this.errors.push(new Errorcalm("No macro name provided", "PREPROCESSING", curLine)) return } if(preprocessing.reservedWords.has(line[1])){ // a macro instruction cannot be a reserved word - this.errors.push(new ErrorCalm("Macro instruction cannot be a reserved word (register or instruction)", "PREPROCESSING", curLine)) + this.errors.push(new Errorcalm("Macro instruction cannot be a reserved word (register or instruction)", "PREPROCESSING", curLine)) return } if([',',':','/','\\','.'].includes(line[1])){ // macro name cannot be a special character - this.errors.push(new ErrorCalm("Macro name cannot be a special character", "PREPROCESSING", curLine)) + this.errors.push(new Errorcalm("Macro name cannot be a special character", "PREPROCESSING", curLine)) return } if(!isNaN(Number(line[1][0]))){ // macro name cannot start with a number or be a number - this.errors.push(new ErrorCalm("Macro name cannot start with a number or be a number", "PREPROCESSING", curLine)) + this.errors.push(new Errorcalm("Macro name cannot start with a number or be a number", "PREPROCESSING", curLine)) return } if(this.macroKeyWord.has(line[1])){ // macro already declared - this.errors.push(new ErrorCalm("Macro already declared", "PREPROCESSING", curLine)) + this.errors.push(new Errorcalm("Macro already declared", "PREPROCESSING", curLine)) return } @@ -215,13 +200,13 @@ class preprocessing{ if(!input[curLine]){ // console.log("not closed, and main function not declared") // end of code without any end of macro or beginning of code - this.errors.push(new ErrorCalm("Macro not closed", "PREPROCESSING", curLine)) + this.errors.push(new Errorcalm("Macro not closed", "PREPROCESSING", curLine)) return } if(input[curLine] === 'START'){ // code starts and macro not closed - this.errors.push(new ErrorCalm("Macro not closed", "PREPROCESSING", curLine)) + this.errors.push(new Errorcalm("Macro not closed", "PREPROCESSING", curLine)) return } @@ -235,13 +220,13 @@ class preprocessing{ line = input[curLine++].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|\d+|,)/g) if(line[0] === 'MACRO'){ // throw error, no macros allowed inside a macro - this.errors.push(new ErrorCalm("No macros allowed inside a macro", "PREPROCESSING", curLine)) + this.errors.push(new Errorcalm("No macros allowed inside a macro", "PREPROCESSING", curLine)) return } if(line[0][line[0].length - 1] === ':'){ // throw error, no labels allowed inside a macro - this.errors.push(new ErrorCalm("No labels allowed inside a macro", "PREPROCESSING", curLine)) + this.errors.push(new Errorcalm("No labels allowed inside a macro", "PREPROCESSING", curLine)) return } macroHolder.body.push(line) @@ -275,7 +260,7 @@ class preprocessing{ while(!endOfCode){ if(!input[curLine]){ // throw error and quit - this.errors.push(new ErrorCalm("no END keyword detected", "PREPROCESSING", curLine)) + this.errors.push(new Errorcalm("no END keyword detected", "PREPROCESSING", curLine)) //console.log("does'nt work") return {error: "this thing doesn't work"} } @@ -291,6 +276,8 @@ class preprocessing{ // replaceMacro(line,output) // pushes directly in the output code output.push( ...this.expandMacro(line,line[1],true)) //output.push('this is a macro') + } else { + output.push(input[curLine - 1]) } } else if(this.macroKeyWord.has(line[0])){ // replace again @@ -318,7 +305,7 @@ class preprocessing{ } if(newLine.length !== expandedMacroTemplate.instruction.length){ //throw error, different number of args - this.errors.push(new ErrorCalm(`Different number of arguments for macro ${newLine[0][newLine.length - 1] === ':' ? newLine[1]: newLine[0]}`, "PREPROCESSING", newLine)) + this.errors.push(new Errorcalm(`Different number of arguments for macro ${newLine[0][newLine.length - 1] === ':' ? newLine[1]: newLine[0]}`, "PREPROCESSING", newLine)) return ["error here"] } //there is no label, direct matching @@ -332,57 +319,106 @@ class preprocessing{ // no errors are handled here // no spaces allowed between labelName and : - detectLabels(code /* */){ - let n = code.length - for(let i = 0; i < n; i++){ - let line = code[i].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|\d+|,)/g) - if(line[0][line[0].length - 1] === ":"){ - if(line[0].length === 1){ - // throw error - console.log("error, empty label") - return - } + // detectLabels(code){ + // console.log(code) + // let n = code.length + // for(let i = 0; i < n; i++){ + // let line = code[i].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|\d+|,)/g) + // if(line[0][line[0].length - 1] === ":"){ + // if(line[0].length === 1){ + // // throw error + // console.log("error, empty label") + // return + // } + + // if(preprocessing.reservedWords.has(line[0].slice(0,-1)) || this.macroKeyWord.has(line[0].slice(0,-1))){ + // // reserved word cannot be a label + // this.errors.push(new Errorcalm("Reserved word cannot be a label", "PREPROCESSING", i)) + // console.log("reserved") + // return + // } + // //label does not start with a number + // if(!isNaN(Number(line[0][0]))){ + // // label cannot start with a number + // this.errors.push(new Errorcalm("Label cannot start with a number", "PREPROCESSING", i)) + // console.log("number") + // return + // } + + // this.labelSymbolList.push({label: line[0].slice(0,-1), line: i + 1}) + // } + // } + // console.log(this.labelSymbolList) + // } + + // removeAndReplaceLabels(code){ + // // replace labels with their line numbers I guess + // let n = code.length + // let output = [] + // for(let i = 0; i < n; i++){ + // //check in each line if there is a use of the label, if definition, we remove it, if use, replace with line number + // let line = code[i].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|\d+|,)/g) + // console.log(line) + // if(line[0][line[0].length - 1] === ":"){ + + // output.push(line.filter(word => word[word.length - 1] !== ':').join(' ')) + // } + // else{ + // output.push(line.join(' ')) + // } + // } + // return output + // } + static preprocessor(code){ + const preprocessor = new preprocessing(); + let str = code + console.log("code 1 here:"+str) + preprocessor.getDataSegment(str) + //console.log("code 2 here:"+str) + if(preprocessor.errors.length > 0){ + Errorcalm.printError(preprocessor.errors) + // force exit + return + } + preprocessor.allocateData() - if(preprocessing.reservedWords.has(line[0].slice(0,-1)) || this.macroKeyWord.has(line[0].slice(0,-1))){ - // reserved word cannot be a label - this.errors.push(new ErrorCalm("Reserved word cannot be a label", "PREPROCESSING", i)) - console.log("reserved") - return - } - //label does not start with a number - if(!isNaN(Number(line[0][0]))){ - // label cannot start with a number - this.errors.push(new ErrorCalm("Label cannot start with a number", "PREPROCESSING", i)) - console.log("number") - return - } + if(preprocessor.errors.length > 0){ + Errorcalm.printError(preprocessor.errors) + // force exit + return + } - this.labelSymbolList.push({label: line[0].slice(0,-1), line: i + 1}) - } + preprocessor.extractMacro(str) + + //console.log("code 2 here:"+str) + if(preprocessor.errors.length > 0){ + Errorcalm.printError(preprocessor.errors) + // force exit + return } - console.log(this.labelSymbolList) - } - removeAndReplaceLabels(code){ - // replace labels with their line numbers I guess - let n = code.length - let output = [] - for(let i = 0; i < n; i++){ - //check in each line if there is a use of the label, if definition, we remove it, if use, replace with line number - let line = code[i].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|\d+|,)/g) - console.log(line) - if(line[0][line[0].length - 1] === ":"){ + str = preprocessor.replaceMacro(str) - output.push(line.filter(word => word[word.length - 1] !== ':').join(' ')) - } - else{ - output.push(line.join(' ')) + console.log("code 2 here:"+str) + if(preprocessor.errors.length > 0){ + Errorcalm.printError(preprocessor.errors) + // force exit + return } - } - return output - } + // preprocessor.detectLabels(str) + + // console.log("code 2 here:"+str) + // if(preprocessor.errors.length > 0){ + // Errorcalm.printError(preprocessor.errors) + // // force exit + // return + // } + // str = preprocessor.removeAndReplaceLabels(str) -} + console.log("code 4 here:"+str) + return {code: str, labels: preprocessor.labelSymbolList, data: preprocessor.data, varList: preprocessor.varList} + + } -module.exports = { preprocessing } \ No newline at end of file +} \ No newline at end of file diff --git a/src/pages/Arch/index.jsx b/src/pages/Arch/index.jsx index e93825c..328db75 100644 --- a/src/pages/Arch/index.jsx +++ b/src/pages/Arch/index.jsx @@ -16,7 +16,8 @@ let [IPval,setipval]=useState(0); let [AluVal,setAluVal]=useState(""); let [MCVal,setMCVal]=useState(""); -let MC=props.mem.getData(); +let MC= props.mem.getData(); +console.log("yokosooooo hereeee's",MC) let tablec=[]; MC.forEach((element,index) => { tablec.push( @@ -66,7 +67,7 @@ MC.forEach((element,index) => { //decalage par 1 gsap.fromTo(".queuearrow",{top:"60%",left:"83%",opacity:"0"},{top:"60%",left:"73%",opacity:"1",duration:0.3}); gsap.to(".queuearrow",{opacity:"0",duration:"0.1",delay:"0.3"}); - if(animqueuelen()==6){ + if(animqueuelen() == 6){ gsap.to(".queue6",{opacity:"0",duration:0.4}) gsap.to(".queue5",{opacity:"1",duration:0.4}) gsap.to(".queue4",{opacity:"1",duration:0.4}) diff --git a/src/pages/Ide/index.jsx b/src/pages/Ide/index.jsx index e4d98d8..15580dc 100644 --- a/src/pages/Ide/index.jsx +++ b/src/pages/Ide/index.jsx @@ -37,7 +37,7 @@ let animations=[]; let Contextarray=[]; ////////////////machine declarations//////////////////////////////// -let memory=new MC(); +let memory = new MC(); let sequenceur=new Sequenceur(); let queue = new Queue(); let addressingModes=new AddressingModes(); @@ -75,7 +75,7 @@ const Ide = ({currentUser})=>{ let [simul,setsimul]=useState(false) let [memo,setmemo]=useState(false); let [reg,setreg]=useState(false); - let [stk,setstk]=useState(false);//for showing stack + let [stk,setstk]=useState(false); //for showing stack let [isHexa,setIsHexa]=useState(false); let [iscode,setIsCode]=useState(true); let [iserr,seterr]=useState(false); @@ -91,7 +91,6 @@ const Ide = ({currentUser})=>{ } memory.setcode(codeArray) - console.log("long waited memory code is here:\n\n"+memory.code) queue.instructionset([]); let numtmp=0; @@ -108,6 +107,7 @@ const Ide = ({currentUser})=>{ console.log(queue.getinstwithoutshift()) let instrobject={}; + memory.data = MC.data while(instrobject.name!=="stop"){ sequenceur.getinstrbyte(animations,true,Contextarray); instrobject={...sequenceur.decode(animations,Contextarray)}; @@ -122,6 +122,7 @@ const Ide = ({currentUser})=>{ let [checktest,setChecktest]=useState(false); /////////////////////returning the component////////////////// + let tablec=[]; memory.getData().forEach( (element,index) => { tablec.push( @@ -170,7 +171,7 @@ const Ide = ({currentUser})=>{ const handleStoreCode = () => { const editor = codeMirrorRef.current.editor; const code = editor.getValue(); // Get the current content of the editor - + // Split the code into lines const lines = code.split('\n'); @@ -333,28 +334,24 @@ const Ide = ({currentUser})=>{ className='ide-exec-button' onClick={()=>{ setdone(true); - let inputouter=[]; + let inputouter; if(iscode){ console.log(handleStoreCode) inputouter=Assembler.assemblecode(handleStoreCode()) - }else{ inputouter=handleStoreCode(); } - let input=convertStrings(inputouter); + let input=convertStrings(inputouter.code); + // not checked yet + memory.data = inputouter.memory; input.push("ff"); - console.log("this is :"+ input) - try { - console.log("hachmi"); if (Errorcalm.errorr === 0) { - console.log("drsas") traitement(input); }else{ - console.log("SIks") setresult(Errorcalm.printError()); seterr(true); @@ -392,10 +389,8 @@ const Ide = ({currentUser})=>{ console.log(arr); console.log("old arr=",arr); localStorage.setItem('arr', JSON.stringify(arr)); - console.log("current local storage : ",localStorage.getItem('arr')) window.location.reload(); }}>re-write - {!iserr &&< button className='ide-exec-button' onClick={()=>{ From a88dd25cc199e3a7ed5f90cb526a1a8dd99324c8 Mon Sep 17 00:00:00 2001 From: redouane-bensaci Date: Wed, 23 Apr 2025 00:26:43 +0100 Subject: [PATCH 09/12] back --- src/assembler/Assembler.js | 30 +++++++++++++++++------------- src/assembler/SemanticAnalysis.js | 20 ++++++++------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/assembler/Assembler.js b/src/assembler/Assembler.js index c00f319..5dc1981 100644 --- a/src/assembler/Assembler.js +++ b/src/assembler/Assembler.js @@ -217,7 +217,7 @@ while (hexString.length < size) { labelobj = Assembler.Labellist.find(element => { return element.name === labelname; }); - console.log(labelname) + if (!(labelobj == null)){ if (labelobj == false) { //error @@ -225,7 +225,8 @@ while (hexString.length < size) { return {type: 'ERROR', value: null}; }else{ return {type: 'NUMBER', value: labelobj.address} - }}, + }} +}, @@ -265,7 +266,8 @@ while (hexString.length < size) { var lastindex ; var index = 0; - + console.log("listlength:",listofpar.length) + console.log("listofpar:",listofpar) while (index < listofpar.length && listofpar[index].value !== ',') { list1.push(listofpar[index]); lastindex = index; @@ -443,7 +445,8 @@ export class Assembler{ if (Errorcalm.LexicalError.length > 0) { Errorcalm.printError(); }else{ - this.input = lexicalList + console.log("lexicalList fjlsjdflsjflsjfs",lexicalList) + this.input = lexicalList; this.toAssemble = new SemanticAnalysis(this.input); // let ret= functinterface.cofirmationfunction(this.input); } @@ -453,8 +456,11 @@ export class Assembler{ //turn instruction object to 8 octet hexa represented as a string // input is one line of code var index = 0; + console.log("input",input) + const element = input[index]; - switch(element.type){ + console.log("input",input[index]) + switch(element.type){ case 'INST2': var opcode='' ; @@ -852,16 +858,13 @@ export class Assembler{ } } } - static assemblecode(input){ - + static assemblecode(input){ let input2 = preprocessing.preprocessor(input) MC.data = Array(100).fill().map((_, i) => FuncInterface.binaryToHexoneByte(input2.data[i] ?? "00000000")) - console.log("MC.data:",MC.data) Assembler.Labellist.push(...input2.varList) - SemanticAnalysis.labeltype = true; let output = new Assembler(input2.code); - var assembledcode = []; - var toassmb = (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"; + var assembledcode = []; + var toassmb = (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"; var ipTrack = 0; var i=0; var lines=(Assembler.Labellist.length === 0 )?toassmb.length:Assembler.Labellist[i].linedeclared; @@ -877,11 +880,12 @@ export class Assembler{ lines=toassmb.length; } } - ipTrack = ipTrack+(Assembler.assemble(toassmb[index]).length/2) + ipTrack = ipTrack+(Assembler.assemble(toassmb[index]).length/2) } - SemanticAnalysis.labeltype = false; + SemanticAnalysis.labeling = false; output = new Assembler(input2.code) toassmb = (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"; + console.log("toassmb",toassmb) for (let index = 0; index < toassmb.length; index++) { assembledcode.push(Assembler.assemble(toassmb[index])) } diff --git a/src/assembler/SemanticAnalysis.js b/src/assembler/SemanticAnalysis.js index 46179e5..caa41f2 100644 --- a/src/assembler/SemanticAnalysis.js +++ b/src/assembler/SemanticAnalysis.js @@ -7,9 +7,10 @@ import { Assembler,FuncInterface } from "./Assembler.js"; export class SemanticAnalysis { Semanticlist = [] - static labeltype = true; + static labeling = true; constructor(input) { let lexicalList = input; + if(SemanticAnalysis.labeling){ for(let i = 0; i < lexicalList.length; i++){ let firstword = lexicalList[i][0] let firstwordtype = firstword.type @@ -24,21 +25,18 @@ export class SemanticAnalysis { var found = false ; var labelname = lexicalList[i][1].value ; Assembler.Labellist.forEach(element => { - if((element.name === labelname) && (SemanticAnalysis.labeltype === element.label)){ + if((element.name === labelname)){ console.log(element.name + " " + labelname + " " + SemanticAnalysis.labeltype + " " + element.label) found = true } }); if (!found) { if (lexicalList[i][1].type === 'TEXTT') { - if (SemanticAnalysis.labeltype){ Assembler.Labellist.push({ name: labelname, address: parseInt(lexicalList[i][2].value), linedeclared:i, label: true }) - } - } - else { - if (!SemanticAnalysis.labeltype){ + } + else if (lexicalList[i][1].type === 'TEXT') { Assembler.Labellist.push({ name: labelname, address: parseInt(lexicalList[i][2].value), linedeclared:i, label: false }) - } + } }else{ this.Semanticlist.push(new Errorcalm("LABEL already declared",null,i)) @@ -62,8 +60,7 @@ export class SemanticAnalysis { } } } - } - if (!SemanticAnalysis.labeltype){ + }} for(let i = 0; i < lexicalList.length; i++){ // here operation with each line of code // we must check if it is a label or an instruction @@ -201,6 +198,7 @@ export class SemanticAnalysis { // check also for first operand based ind and second indexed or based or opposite // check if size of first list == size of second list and assign it to the size of the instruction var list1,list2 =[]; + console.log("lexicalList[i]",lexicalList[i]) list1 = FuncInterface.addrmod(lexicalList[i].slice(1),i).list1 ; //console.log("list1",list1[0].type) list2 = FuncInterface.addrmod(lexicalList[i].slice(1),i).list2 ; @@ -277,8 +275,6 @@ export class SemanticAnalysis { // Label instformat LABEL num check this num if it is valid.; -} - /* const MAXNUM =6000 // max adress for label From 749255e4ed072f781f02a6527a26b6c0f9dc6586 Mon Sep 17 00:00:00 2001 From: nejem Eddine Mekentichi <83135662+Nejmeddine-Mek@users.noreply.github.com> Date: Sun, 27 Apr 2025 20:49:58 +0100 Subject: [PATCH 10/12] added profile, login and sign up forms as well as some debuggings --- Calm | 1 - src/App.js | 4 +- src/assembler/Assembler.js | 39 ++-- src/assembler/Errorcalm.js | 3 +- src/assembler/SemanticAnalysis.js | 6 + src/assembler/preprocessing.js | 93 ++++---- src/assets/Group16.png | Bin 0 -> 2964 bytes src/components/NavBar/index.jsx | 36 ++-- src/components/NavBar/style.css | 162 ++++++++++---- src/components/loginForm/index.jsx | 91 ++++++++ src/components/loginForm/login.css | 72 +++++++ src/components/profileNav/index.jsx | 22 ++ src/components/profileNav/profileNav.css | 71 ++++++ src/components/signUpForm/index.jsx | 118 ++++++++++ src/components/signUpForm/signup.css | 85 ++++++++ src/index.css | 4 +- src/pages/Ide/index.jsx | 16 +- src/pages/Login/index.jsx | 4 +- src/pages/Profile/index.jsx | 262 +++++++++++++---------- src/pages/Profile/profile.css | 168 +++++++++++++++ src/pages/Profile/sample.jpg | Bin 0 -> 10573 bytes src/pages/Profile/style.css | 154 ------------- src/pages/Register/index.jsx | 4 +- 23 files changed, 1029 insertions(+), 386 deletions(-) delete mode 160000 Calm create mode 100644 src/assets/Group16.png create mode 100644 src/components/loginForm/index.jsx create mode 100644 src/components/loginForm/login.css create mode 100644 src/components/profileNav/index.jsx create mode 100644 src/components/profileNav/profileNav.css create mode 100644 src/components/signUpForm/index.jsx create mode 100644 src/components/signUpForm/signup.css create mode 100644 src/pages/Profile/profile.css create mode 100644 src/pages/Profile/sample.jpg delete mode 100644 src/pages/Profile/style.css diff --git a/Calm b/Calm deleted file mode 160000 index 6f82cba..0000000 --- a/Calm +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6f82cbaffeea10c8da04d6ff673f5ac5ebaf5c03 diff --git a/src/App.js b/src/App.js index c49189c..f95e844 100644 --- a/src/App.js +++ b/src/App.js @@ -47,8 +47,8 @@ function App() { - - }/> + }/> + }/> }/> }/> }/> diff --git a/src/assembler/Assembler.js b/src/assembler/Assembler.js index c00f319..adab8e4 100644 --- a/src/assembler/Assembler.js +++ b/src/assembler/Assembler.js @@ -217,9 +217,8 @@ while (hexString.length < size) { labelobj = Assembler.Labellist.find(element => { return element.name === labelname; }); - console.log(labelname) - if (labelobj == false) - { + + if (labelobj === undefined || labelobj === null) { //error Errorcalm.set_SemanticError(new Errorcalm("Label not found",null,linenumber)); return {type: 'ERROR', value: null}; @@ -441,7 +440,8 @@ export class Assembler{ let lexicalList = input.map((t,index)=> {return new Lexer(t,index).LexicalList} ) if (Errorcalm.LexicalError.length > 0) { - Errorcalm.printError(); + const errorMSG = Errorcalm.printError(); + this.input = {error: errorMSG} }else{ this.input = lexicalList this.toAssemble = new SemanticAnalysis(this.input); @@ -855,42 +855,57 @@ export class Assembler{ static assemblecode(input){ let input2 = preprocessing.preprocessor(input) - MC.data = Array(100).fill().map((_, i) => FuncInterface.binaryToHexoneByte(input2.data[i] ?? "00000000")) + if(input2.error !== ''){ + return {code: input2.code, memory: input2.data, error: input2.error} + } + // again, this needs a fix + //this is safe + MC.data = Array(100).fill().map((_, i) => FuncInterface.binaryToHexoneByte(input2.data[i] ?? "00000000")) + console.log("MC.data:",MC.data) Assembler.Labellist.push(...input2.varList) SemanticAnalysis.labeltype = true; + let output = new Assembler(input2.code); + // if semantic analysis returns any error we return it from here + if(output.input?.error){ + return {code: [], memory: MC.data, error: output.error} + } var assembledcode = []; var toassmb = (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"; var ipTrack = 0; var i=0; - var lines=(Assembler.Labellist.length === 0 )?toassmb.length:Assembler.Labellist[i].linedeclared; - // deux pass first pass stays as it is with adding a delimater at each label and then re apply the semantic analysis for the labels and then reassemble the code + var lines = (Assembler.Labellist.length === 0 ) ? toassmb.length : Assembler.Labellist[i].linedeclared; + // two pass first pass stays as it is with adding a delimater at each label and then re apply the semantic analysis for the labels and then reassemble the code if ( Errorcalm.SemanticError.length === 0 ) { for (let index = 0; index < toassmb.length; index++) { if (index >= lines) { Assembler.Labellist[i].address = ipTrack; i++; if (i < Assembler.Labellist.length) { - lines=Assembler.Labellist[i].linedeclared-Assembler.Labellist[i-1].linedeclared-1+index; + lines = Assembler.Labellist[i].linedeclared - Assembler.Labellist[i-1].linedeclared-1+index; }else{ - lines=toassmb.length; + lines = toassmb.length; } } ipTrack = ipTrack+(Assembler.assemble(toassmb[index]).length/2) } SemanticAnalysis.labeltype = false; - output = new Assembler(input2.code) + output = new Assembler(input2.code) + // if semantic analysis returns any error we return it from here + if(output.input?.error){ + return {code: [], memory: MC.data, error: output.error} + } toassmb = (output && output.toAssemble && output.toAssemble.Semanticlist) ? output.toAssemble.Semanticlist : "Semanticlist is undefined"; for (let index = 0; index < toassmb.length; index++) { assembledcode.push(Assembler.assemble(toassmb[index])) } - return {code: assembledcode, memory: memory.data}; + return {code: assembledcode, memory: memory.data, error: input2.error}; // here put the return in case of success }else{ //here put the return in case of error - return "error"; + return {code: assembledcode, memory: memory.data, error: `${Errorcalm.SemanticError[0].message} at line ${Errorcalm.SemanticError[0].line}`}; } } diff --git a/src/assembler/Errorcalm.js b/src/assembler/Errorcalm.js index 9c6d48d..b8207d6 100644 --- a/src/assembler/Errorcalm.js +++ b/src/assembler/Errorcalm.js @@ -45,7 +45,8 @@ export class Errorcalm{ numerr ==1 ? theError="\nThere is 1 error in your code:\n" : theError=`\nThere are ${numerr} errors in your code cannot assemble:\n`; Errorcalm.LexicalError.length == 0 ? theError+=" Semantic Errors:\n"+" "+Errorcalm.SemanticError[0].message+"\n the line : "+Errorcalm.SemanticError[0].linenum : theError+="Lexical Errors \n"+" "+Errorcalm.LexicalError[0].message+"\n the line :"+Errorcalm.LexicalError[0].line; Errorcalm.errorr=1; - return theError;} + return theError; + } } static addtoSemanticError(errs){ Errorcalm.SemanticError= errs.concat(Errorcalm.SemanticError); } diff --git a/src/assembler/SemanticAnalysis.js b/src/assembler/SemanticAnalysis.js index 46179e5..37402a2 100644 --- a/src/assembler/SemanticAnalysis.js +++ b/src/assembler/SemanticAnalysis.js @@ -151,6 +151,12 @@ export class SemanticAnalysis { switch (lexicalList[i].length) { case 2: + const labelType = FuncInterface.Label_To_Num(firstparam.value,i) + if(labelType.type === 'ERROR'){ + this.Semanticlist.push(new Errorcalm("LABEL not declared",null,i)) + // we shall fix this later if needed + return + } this.Semanticlist.push([{type:lexicalList[i][0].type, value:lexicalList[i][0].value, adrmode:0 },{type:FuncInterface.Label_To_Num(firstparam.value,i).type, value:FuncInterface.Label_To_Num(firstparam.value,i).value}]); break; diff --git a/src/assembler/preprocessing.js b/src/assembler/preprocessing.js index 3c26c39..38759e2 100644 --- a/src/assembler/preprocessing.js +++ b/src/assembler/preprocessing.js @@ -22,27 +22,29 @@ export class preprocessing{ getDataSegment(code){ const n = code.length let i = 0 - while( i < n && code[i] !== 'START'){ - if(code[i] === 'SDATA'){ + while( i < n && code[i].toUpperCase() !== 'START'){ + if(code[i].toUpperCase() === 'SDATA'){ i += 1 let endOfSeg = false while(!endOfSeg){ - if(code[i] === 'ENDS'){ - endOfSeg = true - continue - } + if(i === n){ + console.log("no end of data segment") //error segment not closed this.errors.push(new Errorcalm("Data segment not closed", "PREPROCESSING", i)) return } + if(code[i].toUpperCase() === 'ENDS'){ + endOfSeg = true + continue + } + this.dataSegment.push(code[i++]) } break } i += 1 } - console.log('data: ', this.dataSegment) } // allocate space in memory, to get addresses of variables @@ -64,7 +66,7 @@ export class preprocessing{ this.errors.push(new Errorcalm("Wrong variable declaration", "PREPROCESSING", i)) return } - if(this.varList.includes(line[0])){ + if(this.varList.includes(line[0].toUpperCase())){ // throw error, variable already declared this.errors.push(new Errorcalm("Variable already declared", "PREPROCESSING", i)) return @@ -79,15 +81,15 @@ export class preprocessing{ // assign the name of the var to the corresponding object varHolder.label = false varHolder.linedeclared = i - varHolder.name = line[0] + varHolder.name = line[0].toUpperCase() varHolder.address ??= curAddress this.varList.push(varHolder) - if(!(['DB', 'DW']).includes(line[1])){ + if(!(['DB', 'DW']).includes(line[1].toUpperCase())){ // throw error, wrong variable length declaration this.errors.push(new Errorcalm("Wrong variable type", "PREPROCESSING", i)) return } - let length = line[1] === 'DB' ? 0 : 1 // data on one byte or on two bytes if line[0] === 'DW' + let length = line[1].toUpperCase() === 'DB' ? 0 : 1 // data on one byte or on two bytes if line[0] === 'DW' varHolder.length = length let value = line.filter((_,index) => index >= 2).join(" ").match(/"[^"]*"|[^,]+/g) @@ -107,7 +109,8 @@ export class preprocessing{ if(length === 1){ if(val <= Math.abs(Math.pow(2,16))){ // use 2s complement instead of this expression - val = FuncInterface.decimalTobinByte(val,1) + console.log(val) + val = FuncInterface.decimalTobinByte(val,16) return [String(val).substring(0,Math.floor(val.length / 2)), String(val).substring(Math.floor(val.length / 2))] } else { @@ -117,7 +120,7 @@ export class preprocessing{ } else { if(val <= Math.abs(Math.pow(2,8))){ // use 2s complement instead of this expression - return FuncInterface.decimalTobinByte(val,0) + return FuncInterface.decimalTobinByte(val,8) } else { this.errors.push(new Errorcalm("value out of bounds", "PREPROCESSING", index)) return null @@ -136,13 +139,13 @@ export class preprocessing{ } //ascii characters are positive integers between 0 and 255 - return val.split('').filter(char => char !== '"').map(char => ['00000000',char.charCodeAt(0).toString(2).padStart(8,'0')]).flat() + return val.split('').filter(char => char !== '"').map(char => ['00000000', char.charCodeAt(0).toString(2).padStart(8,'0')]).flat() } }).flat() // flatten to get a 1 dimensional array just in case if we have a string in the object //we have to work on this this.data.push(...value) } - console.log(this.varList) + console.log(this.data) } // we suppose the code is given to use as @@ -217,7 +220,7 @@ export class preprocessing{ } // making sure no sort of label is declared inside a macro - line = input[curLine++].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|\d+|,)/g) + line = input[curLine++].match(/[a-zA-Z_][a-zA-Z0-9_*]*|[,:+-]|\d+/g) if(line[0] === 'MACRO'){ // throw error, no macros allowed inside a macro this.errors.push(new Errorcalm("No macros allowed inside a macro", "PREPROCESSING", curLine)) @@ -252,7 +255,7 @@ export class preprocessing{ curLine += 1 if(!input[curLine]){ // throw error - console.log("No end") + this.errors.push(new Errorcalm("no START keyword detected", "PREPROCESSING", curLine)) return } } @@ -268,7 +271,7 @@ export class preprocessing{ endOfCode = true continue } - let line = input[curLine++].match(/([a-zA-Z_][a-zA-Z0-9_]*:?|\d+|,)/g) + let line = input[curLine++].match(/[a-zA-Z_][a-zA-Z0-9_*]*|[,:+-]|\d+/g) if(line[0][line[0].length - 1] === ':'){ if(this.macroKeyWord.has(line[1])){ @@ -311,7 +314,10 @@ export class preprocessing{ //there is no label, direct matching for(let i = newLine.length - 1; i >= 1; i--){ - body = body.map(inst => inst.replace(expandedMacroTemplate.instruction[i], newLine[i])) + const wordToReplace = expandedMacroTemplate.instruction[i]; + const regex = new RegExp(`\\b${wordToReplace}\\*?\\b`, "g"); + + body = body.map(inst => inst.replace(regex, newLine[i])); } return body @@ -372,32 +378,37 @@ export class preprocessing{ static preprocessor(code){ const preprocessor = new preprocessing(); let str = code - console.log("code 1 here:"+str) - preprocessor.getDataSegment(str) - //console.log("code 2 here:"+str) - if(preprocessor.errors.length > 0){ - Errorcalm.printError(preprocessor.errors) - // force exit - return - } - preprocessor.allocateData() + try{ + + preprocessor.getDataSegment(str) + console.log(preprocessor.errors.length) + console.log(preprocessor.errors) + if(preprocessor.errors.length > 0){ + return {code: [], labels: [], data: [], varList: [], error: `Error: ${preprocessor.errors[0].message}\n${preprocessor.errors[0].type}`} + } + str = str.map(line => line.toUpperCase()) + preprocessor.allocateData() + if(preprocessor.errors.length > 0){ + return {code: [], labels: [], data: [], varList: [], error: `Error: ${preprocessor.errors[preprocessor.errors.length - 1].message}\n${preprocessor.errors[preprocessor.errors.length - 1].type} in line ${preprocessor.errors[preprocessor.errors.length - 1].linenum} in data segment`} + } + preprocessor.extractMacro(str) + + if(preprocessor.errors.length > 0){ + return {code: [], labels: [], data: [], varList: [], error: `Error: ${preprocessor.errors[preprocessor.errors.length - 1].message}\n${preprocessor.errors[preprocessor.errors.length - 1].type} in line ${preprocessor.errors[preprocessor.errors.length - 1].linenum} in macro declaration`} + } + str = preprocessor.replaceMacro(str) + if(preprocessor.errors.length > 0){ + return {code: [], labels: [], data: [], varList: [], error: `Error: ${preprocessor.errors[preprocessor.errors.length - 1].message}\n${preprocessor.errors[preprocessor.errors.length - 1].type} in line ${preprocessor.errors[preprocessor.errors.length - 1].linenum} in code segment`} + } + return {code: str || [], labels: preprocessor.labelSymbolList, data: preprocessor.data, varList: preprocessor.varList, error: ''} - if(preprocessor.errors.length > 0){ - Errorcalm.printError(preprocessor.errors) - // force exit - return + }catch(err){ + return {code: [], labels: [], data: [], varList: [], error: `Something went wrong, inner issue!`} } - preprocessor.extractMacro(str) - //console.log("code 2 here:"+str) - if(preprocessor.errors.length > 0){ - Errorcalm.printError(preprocessor.errors) - // force exit - return - } - str = preprocessor.replaceMacro(str) + console.log("code 2 here:"+str) if(preprocessor.errors.length > 0){ @@ -417,7 +428,7 @@ export class preprocessing{ console.log("code 4 here:"+str) - return {code: str, labels: preprocessor.labelSymbolList, data: preprocessor.data, varList: preprocessor.varList} + } diff --git a/src/assets/Group16.png b/src/assets/Group16.png new file mode 100644 index 0000000000000000000000000000000000000000..9770ad53191bf2c6b6e68d4101d441efd0759178 GIT binary patch literal 2964 zcmV;F3v2X=P)4u#|65sH4o5n23>cecHL>*?gv)dZGmL=1?+TPAjxc7 zz|Oi0JL@i79*dgLG$oOeZ29B-03xv{@=&r44@Djx1NG3BX)4oLrmiLbT;<=&B#b=z zJd|m!&NJz1b+^GV%*II-l+x75YioIw`bK`=$QMTbSj!uNVHjuri+T{+|1BfW{QRsS zU*vo?^B9K7p)Lhy7-kD$1!tH&h83J)_83-hhS_8OhicFSnZW8qS)l!YVkx8N9~=2a zOJRXbcQVbuFih=`g3@}mzI@e0qBZp%cxIhpYNLZ>oqN7TX$-q_4O5O7#rHh4lpDhT zyE}tFW#mLSP<-CO&tTtYi1d@mH9L%oq9DbOucT54U3Lawnd%*~7$#;zaeg>lh z#tRn(7uX%^NN%s&Ho{=?2|dmYz% znteX9Q*(S(>ze2Wm;x3LPw*pe|0rqeCp@ZyeqT`>UI@B@J zgGZg<$5`Fx{(!`#meK_EB9M$y+J@XmBp!bEO0JEx-6pe~GV3O7(USTlYdt!`dfHZoK&D}EdOGjFc{88>{r7zS&p%FS_}g#u z?w4PtZnfv|hZK7n$~vg75;BEW*YN7sUzg5({@G`AUb+MoV{@*mdYWcjyQo<2LA$D^ zQ12O9QjF$r=2?k03^J}KfIrkxk;QXXuB#sR=5U>ZI%#yw6RK|b)SxV;M?c4d$ z(Ge+6SJgQ+J11$;sZHsyJw`JMPARa|8`e;71jb4TzZ*HkdhmUCLezth>9+UPSGg9O z@^1h5W6=T7-y-XN{>?Yk#xe3oIV5{b=jL`AQt@@!wsYvXQu3Z0)~~c3%hoeSa|+&H zQ@s%wD*&w_b*Z<&;Nq&ANvARl1rV8-ocPO^Zh$YMiY@P8|zbWmvaKG&akFBBOEXS$u`iTC5_>ySZ2NR z3Q1I`>o((huHg3WyE2qb-=USo_L)Q!B$uqY%@SkPiif0_HrdoBPuY>KGjwnU(dD^(uJiaGrqMyh|Ib;JJ{a z%eOLJ;Bff1AipEuy_XKeKmUx;&CLYW9+c5+Hk*9@#TTOW?8*7;{{4IUle!6aW#_U~ zh@4RRKm9a8al7-lyuZKi$CoIQDGD!p93c7}ZN8f!% zf9P5!D9;^v)U61;xk+Vjl9`ejH?@*mlPF{yxPff_}RPrO%z+EzWXu|)T?q!gZpO=?%38oPK;e%yPPmN*h{oUgE z-^4I>rE}5z*e6&6%BnY^;Mb@|ItpM4UhRI6@HmC$b-vC0WcjO0Dr)}0v*Cpo! zn)(5W395BkH(;C~1@9tzCcVncZIe*DZPznKe&p2^C6h|9_=ELxd~Ce?)9V51vEC=< z$V7Eqb#xwOsWQaA0^n{1a^vEb^}V}#}yp*(EC9Z4g)91?lfcs6@n z-ny=4)CH+IWPEC2HV<>=Y`+LaG{mdkF8^?I`DbR5d$J!56%9t?HQq6_VRvY<3NNSAqh(hDqG zV1dnW7yt6h%E628zo$O~lpD=lNG0t=uU{`6RL(Oop04v+4V#zfCDyl$vr$*B2=t{g zuVmaew>)Mtg5Lz@1Ux*il@NZt>$+w)W6ySkD9_O5x2*+f5RUcGd5dT)W&j9nHVO*4P zJ)&3~0#XiJR2EWlwfkzI+GW;9pF^33bl%0AH&z8x!|uo;JEFbjwlZ1=)5EHtb_-A6 z*CKXX+J0NW2_?Usas4qitKesF`%bf-t+H|thI9BUP+rpGe^sS}`hSo7+(B;NwxcYy zz7*$-EVEMf4~eWYm7{!H2SLZe#CpaVau<DbbB5YZH`6J=7Bd$mc;Z8S0j>YSIEW z#07HO6hAF%cx@_cR{N+tbvOb0{yc`l>;S z78H~tr=BPy&kVGwGeY*yO;we<*Ayu@&9oN9Fxy7xVHjb3(0vgyk*1~5Sm*&IKi72K zzwQkxElsX4WRAe=!;FO@1t;=))@_6o>j(_PIC-+|TI7stFbw02K(iBOzDa;#7%zOh zjhajm7=|fDjO|wLJ{X3nM1<{B?g$LS)PlfvSaX`)ryW*pFbreGWtl7seO>kf%S&l5 zwEyXxp7xnSiNxCHE|wh?$SGl>eI984(-PP#JpHOg-D}MZ!&n$&*}CckM&7{4kB$7m z$k+46U>L?3j*HGPdkiZ$!|XAv;0&|Ju!1wp9S6i^}fmFRU<3qx=gNE7I#WdEt!!0000< KMNUMnLSTaZ8?pER literal 0 HcmV?d00001 diff --git a/src/components/NavBar/index.jsx b/src/components/NavBar/index.jsx index d2a57dc..1e22ba0 100644 --- a/src/components/NavBar/index.jsx +++ b/src/components/NavBar/index.jsx @@ -1,26 +1,30 @@ -import { Link } from "react-router-dom"; -import logo from "../../assets/images/logos/logo.png" +import { Link , useNavigate} from "react-router-dom"; +import logo from "../../assets/Group16.png" import "./style.css"; - const NavBar = () => { + // we need to be redirected to signup / login forms or profile on click + const navigate = useNavigate(); + + const handleLoginClick = () => { + navigate('/login'); + } + const handleSignUpClick = () => { + navigate('/register'); + } + return ( - + + + ); } diff --git a/src/components/NavBar/style.css b/src/components/NavBar/style.css index 1f49513..03c9f3f 100644 --- a/src/components/NavBar/style.css +++ b/src/components/NavBar/style.css @@ -1,64 +1,140 @@ -.navbar{ +body{ + font-family: lato, sans-serif; + align-items: center; + justify-content: center; + background-color: #0B1215; +} +.navbar-container{ display: flex; + flex-direction: row; + position: relative; + justify-self: center; + align-self: center; align-items: center; - flex-wrap: wrap; - gap: 25%; - background-color: #1BE985; - padding: 0 3.1rem; - box-shadow: 0 5px 15px #000, 0 30px 30px rgba(0, 0, 0, 0.08), - 0 15px 15px rgba(0, 0, 0, 0.08), 0 10px 8px rgba(0, 0, 0.08), - 0 4px 4px rgba(0, 0, 0, 0.08), 0 2px 2px rgba(0, 0, 0, 0.08); - border-radius: 2.5rem; - margin: 1% auto; - + justify-content: center; + border-radius: 72px; + border: 2px solid #000; + background: #1BE985; + width: 90%; + height: 70px; + flex-shrink: 0; position: sticky; - top: 1%; - width: 75%; + top: 2%; z-index: 10; } +.website-logo{ + position: absolute; + left: 2%; + top: 50%; + transform: translate(0, -50%); + width: 15%; + height: auto; +} -.links{ - width: 60%; +.website-logo img{ + width: 80%; + height: auto; + justify-self: end; + align-self: center; +} +.navbar-container ul{ + justify-self: center; + align-self: center; + display: flex; + flex-direction: row; + list-style-type: none; + margin: 5%; + padding: 5%; + gap: 20px; } -.links ul{ +.navbar-container ul li { + margin: 0 30px; + text-decoration: none; display: flex; + flex-direction: column; + height: 100%; align-items: center; - justify-content: space-between; } -.a { - text-decoration: none; - list-style: none; - position: relative; - display: block; + +.navbar-container ul li, li:focus, li:active, li::before, li::after { + outline: none; + border: none; +} + +/*we should fix this later, Idk how it works*/ +.navbar-container ul li .circle{ + border-radius: 50%; + background-color: #000000; + width: 0px; + height: 0px; + margin-top: -5px; + opacity: 0; + transform: scale(0); + transition: all 0.5s ease-in-out; +} + +.navbar-container ul li a{ font-size: 1.25rem; - font-weight: 900; - color: #24292E; - font-family: 'Mona Sans', system-ui; + font-weight: bold; + color: rgb(0, 0, 0); + text-decoration: none; + transition: 0.5s ease-in-out; +} + + +.navbar-container ul li a:active, a::after{ + text-decoration: none; + color: rgb(0, 0, 0); +} + +.navbar-container ul li a:hover{ + color: #000000; + text-decoration: none; + font-size: calc(1.25rem + 0.5vw); } -.a :after{ - content: ""; - width: 0%; - height: 2px; - display: block; - margin-top: auto; - align-items: center; - transition: 0.5s; +/* here we should add the circles that appear below the option hovered over*/ +.navbar-container ul li:hover .circle{ + height: 8px; + width: 8px; + visibility: visible; + transition: all 0.5s ease-in-out; + opacity: 1; + transform: scale(1); } -.a :hover::after{ - width: 100%; - background:#24292E; + + +.navbar-container .signup{ + position: absolute; + right: 1%; + border-radius: 72px; + height: calc(100% - 19px); + width: calc(10% - 20px); + border: 2px solid #272626; + background: #D2F6E3; + backdrop-filter: blur(50px); + + font-size: 1.15rem; + font-weight: bold; } -.a li{ - display: inline-block; - font-weight: 900; - font-size: 1.875rem; - transition: 1s; +.navbar-container .signup:hover{ + cursor: pointer; } -.a li:hover{ - transform: scale(1.3,1.3); + +.navbar-container .login{ + position: absolute; + right: 11%; + background-color: transparent; + border: none; + font-size: 1.2rem; + font-weight: bold; } + +.navbar-container .login:hover{ + cursor: pointer; + +} \ No newline at end of file diff --git a/src/components/loginForm/index.jsx b/src/components/loginForm/index.jsx new file mode 100644 index 0000000..fbcbb65 --- /dev/null +++ b/src/components/loginForm/index.jsx @@ -0,0 +1,91 @@ +import Navbar from "../NavBar/index.jsx" +import "./login.css" +import { useState } from "react" +import { useNavigate } from "react-router-dom" +function LoginForm(){ + const [email, setEmail] = useState("") + const [password, setPassword] = useState("") + const navigate = useNavigate() + const submitInfo = async (e) => { + + const emailField = document.getElementById("email") + const passwordField = document.getElementById("password") + e.preventDefault() + // if one of the fields is empty, set the border to red and return + if(email === "" || password === ""){ + + emailField.style.border = "1px solid red" + passwordField.style.border = "1px solid red" + alert("Please fill in all fields") + return + + } else { + emailField.style.border = "1px solid black" + passwordField.style.border = "1px solid black" + } + // now we can send the data to the server + // first verify if we have a valid email + const isEmail = (val) => { + const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return regex.test(val); + } + if(!isEmail(email)){ + emailField.style.border = "1px solid red" + alert("Please enter a valid email") + return + } + // now we are ready to send the data to the server + const res = await fetch("http://localhost:5000/login", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + email: email, + password: password + }) + }) + if(!res.ok){ + const err = await res.json() + alert(err.error) + emailField.style.border = "1px solid red" + passwordField.style.border = "1px solid red" + return + } + // now we have a valid response, we shall parse it and navigate to profile + const data = await res.json() + console.log(data) + // fetch here + + //get result, store token in local storage, then redirect to profile + //then store in local storage + data.modified ??= false + localStorage.setItem("user", JSON.stringify(data)) + + //navigate to profile page or wherever + navigate("/profile") + } + + + return( + <> + +
+

Login

+
+ + setEmail(e.target.value)}> +
+
+ + setPassword(e.target.value)}> +
+

+ + +
+ + ) +} + +export default LoginForm \ No newline at end of file diff --git a/src/components/loginForm/login.css b/src/components/loginForm/login.css new file mode 100644 index 0000000..061d687 --- /dev/null +++ b/src/components/loginForm/login.css @@ -0,0 +1,72 @@ + +#loginForm{ + + justify-self: center; + align-self: center; + background-color: white; + margin: 50px 5px; + border: 2px solid black; + color: black; + /*border-radius: 10px; */ + width: 400px; + height: 450px; + padding: 30px 15px; + position: relative; + display: flex; + flex-direction: column; + justify-content: center; + +} + +.infoContainer{ + display: flex; + flex-direction: column; + justify-content: center; + text-align: left; + margin: 20px 0 0 0; +} +#loginForm h1{ + align-self: center; + margin: 25px 30px; +} + +#loginForm label{ + margin-left: 15%; +} + +#loginForm input{ + height: 45px; + width: 70%; + + align-self: center; + +} + +#loginForm button{ + width: 65%; + height: 45px; + align-self: center; + margin-top: auto; + margin-bottom: 30px; + border: none; + font-size: 18px; + padding: 5px 8px; + color: white; + background-color: #12b264; + transition: all ease-in-out .5s; +} + +#loginForm button:hover{ + background-color:hsl(151, 86%, 22%); + cursor: pointer; + +} + +#loginForm input { + outline: none; + border: 1px solid grey; + border-radius: 4px; + margin: 8px 8px; + font-size: 1.05rem; + padding: 3px 3px; +} diff --git a/src/components/profileNav/index.jsx b/src/components/profileNav/index.jsx new file mode 100644 index 0000000..f71f917 --- /dev/null +++ b/src/components/profileNav/index.jsx @@ -0,0 +1,22 @@ +import "./profileNav.css" +import logo from "../../assets/Group16.png" +import { Link } from "react-router-dom" +function ProfileNav(props){ + return( + <> + + + ) +} + +export default ProfileNav \ No newline at end of file diff --git a/src/components/profileNav/profileNav.css b/src/components/profileNav/profileNav.css new file mode 100644 index 0000000..aa44e03 --- /dev/null +++ b/src/components/profileNav/profileNav.css @@ -0,0 +1,71 @@ +.vertical-navbar{ + margin: 3%; + position: relative; + width: 296px; + height: auto; + flex-shrink: 0; + border-radius: 24px; + border: 2px solid #000; + background: #1BE985; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + +} + +.vertical-navbar .calM-logo img{ + position: absolute; + margin: 20px 10px; + width: 80%; + height: auto; + align-self: center; + left: 50%; + top: 5%; + transform: translate(-50%, -50%); +} + +.vertical-navbar ul{ + list-style: none; + padding: 10% 50%; +} +.vertical-navbar ul{ + margin-top: 30%; +} +.vertical-navbar ul li{ + display: flex; + align-items: center; + padding: 0 8px; + margin: 40px 0; + height: 45px; + width: 100%; + transform: all 0.5s ease-in-out; + border-radius: 8px; +} + +.vertical-navbar ul li a{ + margin: 50px 0; + font-size: 1.2rem; + font-weight: bold; + color: #000; + text-decoration: none; + cursor: pointer; + transition: all 0.5s ease-in-out; + + } + + /* change and fix colors here later*/ + +.vertical-navbar ul li:hover{ + background: rgba(11, 18, 21, 0.17); + cursor: pointer; + transition: all 0.5s ease-in-out; + +} + + .vertical-navbar ul li a:active, a::after{ + color: #000; + text-decoration: none; + cursor: pointer; + transition: all 0.3s ease-in-out; +} \ No newline at end of file diff --git a/src/components/signUpForm/index.jsx b/src/components/signUpForm/index.jsx new file mode 100644 index 0000000..56baf35 --- /dev/null +++ b/src/components/signUpForm/index.jsx @@ -0,0 +1,118 @@ +import isEmail from "validator/lib/isEmail" +import "./signup.css" +import Navbar from "../NavBar/index.jsx" +import { useState } from "react" +import { use } from "react" +function SignUpForm(){ + const [name, setName] = useState("") + const [lastName, setLastName] = useState("") + const [age, setAge] = useState("") + const [email, setEmail] = useState("") + const [username, setUsername] = useState("") + const [password, setPassword] = useState("") + const [confirmPassword, setConfirmPassword] = useState("") + const [gender, setGender] = useState("") + + + const handleNameChange = (e) => setName(e.target.value) + const handleLastNameChange = (e) => setLastName(e.target.value) + const handleAgeChange = (e) => setAge(e.target.value) + const handleEmailChange = (e) => setEmail(e.target.value) + const handleUsernameChange = (e) => setUsername(e.target.value) + const handlePasswordChange = (e) => setPassword(e.target.value) + const handleConfirmPasswordChange = (e) => setConfirmPassword(e.target.value) + const handleGenderChange = (e) => setGender(e.target.value) + + const isEmail = (val) => { + const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return regex.test(val); + } + + const submitInfo = async (e) => { + e.preventDefault() + if(name === "" || lastName === "" || age === "" || email === "" || username === "" || password === "" || confirmPassword === ""){ + alert("Please fill in all fields") + // I might probably highlight the fields that are empty in red + return + } + + if(!isEmail(email)){ + alert("Please enter a valid email address") + return + } + + if(password !== confirmPassword){ + alert("Passwords do not match") + return + } + if(password.length < 8){ + alert("Password must be at least 8 characters long") + return + } + + + const data = { + name: name, + lastName: lastName, + age: Number(age), + email: email, + username: username, + password: password, + confirmPassword: confirmPassword, + } + + console.log(data) + + const res = await fetch("http://localhost:5000/signup", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(data) + }) + if(!res.ok){ + alert("Error signing up") + return + } + const genData = await res.json() + + genData.modified ??= false + + localStorage.setItem("user", JSON.stringify(genData)) + // verify email + + //after verification is done, redirect to profile page + } + + + + return ( + <> + +
+

Sign Up

+
+ + + +
+ +
+ + + + + +
+ + +
+ + ) +} + +export default SignUpForm \ No newline at end of file diff --git a/src/components/signUpForm/signup.css b/src/components/signUpForm/signup.css new file mode 100644 index 0000000..51a7a96 --- /dev/null +++ b/src/components/signUpForm/signup.css @@ -0,0 +1,85 @@ + + +#signUpForm{ + border: 2px solid black; + background-color: white; + align-self: center; + justify-content: center; + width: 60%; + align-self: center; + justify-self: center; + text-align: center; + margin-top: 50px; + border-radius: 5px; + color: black; +} + + +#signUpForm .inputs{ + align-items: center; + justify-content: center; + display: grid; + grid-template-columns: repeat(2, 1fr); + width: 100%; + height: auto; +} + +#signUpForm .inputs input, .gender{ + width: 80%; + height: 45px; + margin: 10px auto; + border-radius: 5px; + border: 1px solid grey; + outline: none; + padding: 3px 10px; +} + +#signUpForm .inputs input:focus{ + border: 1px solid black; +} + + +#signUpForm button{ + width: 20%; + height: 45px; + align-self: center; + margin-top: auto; + margin-bottom: 30px; + border: none; + font-size: 18px; + padding: 5px 8px; + color: white; + background-color: #12b264; + + margin-top: 30px; + transition: all ease-in-out .5s; +} + +#signUpForm .gender{ + display: flex; + justify-content: left; +} + +#signUpForm .inputs select { + width: 100%; + height: 100%; + margin: 10px auto; + border-radius: 5px; + border: 1px solid grey; + outline: none; + padding: 0; + border: none; + outline: none; + justify-self: center; + align-self: center; +} + +#signUpForm button:hover{ + background-color:#0a713f; + cursor: pointer; + + +} + + + diff --git a/src/index.css b/src/index.css index 83b564d..897a869 100644 --- a/src/index.css +++ b/src/index.css @@ -1,9 +1,9 @@ @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@500&display=swap'); @import url('https://fonts.cdnfonts.com/css/mona-sans'); @import url('https://fonts.cdnfonts.com/css/hubot-sans'); - +@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@200..1000&family=Gugi&family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&family=Noto+Serif+JP:wght@200..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); @font-face { - font-family: "Mona Sans"; + font-family: 'lato',"Mona Sans"; src: url("assets/font/Mona-Sans.woff2") format("woff2 supports variations"), url("assets/font/Mona-Sans.woff2") format("woff2-variations"); font-weight: 200 900; font-stretch: 75% 125%; diff --git a/src/pages/Ide/index.jsx b/src/pages/Ide/index.jsx index 48ae986..5076d8a 100644 --- a/src/pages/Ide/index.jsx +++ b/src/pages/Ide/index.jsx @@ -60,7 +60,7 @@ const handleRefresh = () => { function convertStrings(arr) { const result = [] ; for (let i = 0; i < arr.length; i++) { - for (let j = 0; j < arr[i].length; j += 2) { + for (let j = 0; j < arr[i]?.length || 0; j += 2) { result.push(arr[i][j] + arr[i][j+1]); } } @@ -196,7 +196,7 @@ const Ide = ({currentUser})=>{ if (lineWithoutComment !== '') { // If the line without comments is not empty, store it in codeArray - codeArray.push(lineWithoutComment.toUpperCase()); + codeArray.push(lineWithoutComment); } }); @@ -343,6 +343,16 @@ const Ide = ({currentUser})=>{ }else{ inputouter=handleStoreCode(); } + console.log("inputouter",inputouter); + console.log(inputouter.error) + //here I must check for errors, if there are any, we must quit, but quitting is causing an undefined return from somewhere!! + // we shall figure out a solution and put this block back once again + if(inputouter.error !== ''){ + setresult(inputouter.error); + seterr(true); + return + } + let input=convertStrings(inputouter.code); // not checked yet memory.data = inputouter.memory; @@ -368,7 +378,7 @@ const Ide = ({currentUser})=>{ setresult("this is not hexa code"); } - + }}> execute diff --git a/src/pages/Login/index.jsx b/src/pages/Login/index.jsx index 5b06f05..5477782 100644 --- a/src/pages/Login/index.jsx +++ b/src/pages/Login/index.jsx @@ -1,9 +1,11 @@ import React from 'react' import {AuthForm} from '../../components/' +import LoginForm from '../../components/loginForm/index.jsx' const Login = ({updateCurrentUser}) => { return ( - + + ) } diff --git a/src/pages/Profile/index.jsx b/src/pages/Profile/index.jsx index 0e60baa..4818547 100644 --- a/src/pages/Profile/index.jsx +++ b/src/pages/Profile/index.jsx @@ -1,125 +1,171 @@ -import React, { useEffect, useState } from 'react' -import { Link } from "react-router-dom"; -import { NavBar } from '../../components' -import './style.css' -import axios from 'axios' -import { useNavigate } from 'react-router-dom' -import { ProgramContainer } from '../../components'; -import { motion } from 'framer-motion'; -import {Footer} from "../../containers"; +import "./profile.css" +import ProfileNav from "../../components/profileNav/index.jsx" +import pic from "./sample.jpg" +import { useState } from "react" +import { color } from "framer-motion" +import { red } from "@mui/material/colors" +function Profile(){ + const user = localStorage.getItem('user') + const {data} = JSON.parse(user) -const Profile = ({currentUser, updateCurrentUser}) => { - const navigate = useNavigate(); - const [programs, setPrograms] = useState(null); - - useEffect( () => { - if(currentUser === null) return; - - const URL = process.env.REACT_APP_API_URL + `/user/${currentUser.id}/code/all`; + const [hoveredOverConfirm,setHoveredOverConfirm] = useState(false) + const [hoveredOverCancel,setHoveredOverCancel] = useState(false) + const Hover = (e) => { + if(e === 1){ + setHoveredOverConfirm(true) + } else { + setHoveredOverCancel(true) + } - axios.get(URL) - .then((response) => { - console.log(response.data.data); - setPrograms(response.data.data); - }) - .catch((error) => { - console.error(error); - alert("Failed to load programs... Please try again"); - }); - }, [currentUser]); + } + const unhover = (e) => { + if(e === 1){ + setHoveredOverConfirm(false) + } else { + setHoveredOverCancel(false) + } + } + const [name, setName] = useState(data.name) + const [username, setUsername] = useState(data.username) + const [age, setAge] = useState(data.age) + const [email, setEmail] = useState(data.email) + const [lastName, setLastName] = useState(data.lastName) + const [gender, setGender] = useState(data.gender) + const [university, setUniversity] = useState("") + const [yearOfStudy, setYearOfStudy] = useState("") + const [popUp, setPopUp] = useState(false) + const [attribute, setAttribute] = useState("") + const [type, setType] = useState("text") + const editName = () => { + setAttribute("Name") + setType("text") + setPopUp(true) - const handlePasswordResetRequest = (e) => { - const URL = process.env.REACT_APP_API_URL + `/reset-password/request/${currentUser.id}`; + } - axios.post(URL) - .then(response =>{ - navigate('/reset-password/email-sent'); - }) - .catch(error =>{ - console.log(error); - alert("Request failed, please try again."); - }) + const editLastName = () => { + setAttribute("last name") + setType("text") + setPopUp(true) } - const logout = () => { - const URL = process.env.REACT_APP_API_URL + '/logout'; - axios.post(URL) - .then(res => { - updateCurrentUser(null); - localStorage.removeItem('user'); - navigate('/'); - }) - .catch(err => { - console.log(err); - alert("Logout Failed, server isn't responding"); - }) + const editAge = () => { + setAttribute("age") + setType("number") + + setPopUp(true) + } + + const editEmail = () => { + setAttribute("email") + setType("email") + setPopUp(true) + // then verify!! + } - const removeProgram = (targetProgram) => { - setPrograms(programs.filter(program => program.id !== targetProgram.id)) + const editUniversity = () => { + setAttribute("university") + setType("text") + setPopUp(true) } - return ( - <> - -
- {!currentUser - ? - <> -

No user is logged in

-

You can login here

- - : - <> + const editUsername = () => { + setAttribute("university") + setType("text") + setPopUp(true) + //requires verifying uniqueness + } -
-

Profile Information

-
-

Email: {currentUser.email}

-

Score: {currentUser.score}

+ const editYearOfStudy = () => { + setAttribute("university") + setType("text") + setPopUp(true) + } + const Done = () => { + // save changes then close + setPopUp(false) + } + const Cancel = () => { + setPopUp(false) + } + const Logout = async () => { + // handle logout here + } -
-

Saved Programs

- {programs === null - ?

Loading programs...

- : programs.length === 0 - ? -

No programs saved for this profile!

- : -
- { - programs.slice(0).reverse().map(program => - - ) - } -
- } -
- + return( +
+ +
+
+ profile picture +
+

{`${name} ${lastName}` || "Full name"}

+

calM-ID: { ` ${username}` || " "}

+
+ +
-
- Reset Password - Logout -
- - } - - +
+

Basic information

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name:

{`${name }` || "Lorem ipsum"}

LastName:

{`${lastName}` || "Lorem ipsum"}

Username:

{username || "Lorem ipsum"}

Gender:

{gender || "Lorem ipsum"}

Age:

{age || "Lorem ipsum"}

University:

{university || "Lorem ipsum"}

Year of Study:

{yearOfStudy || "Lorem ipsum"}

Email:

{email || "Lorem ipsum"}

+
-
- + { popUp &&( +
+ + +
+ + +
+
+ )} +
+ ) } -export default Profile +export default Profile \ No newline at end of file diff --git a/src/pages/Profile/profile.css b/src/pages/Profile/profile.css new file mode 100644 index 0000000..ac03c1d --- /dev/null +++ b/src/pages/Profile/profile.css @@ -0,0 +1,168 @@ + +.container-profile{ + width: 100%; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + color: black; + margin-bottom: 30px; +} + +.container-profile .personal-information{ + margin-top: 5%; + display: flex; + flex-direction: column; + border-radius: 10px; + align-items: center; + background-color: #C3F9DF; + width: 70%; + height: auto; + z-index: 10; +} + +.container-profile .personal-information .profile-picture{ + height: 15%; + width: 100%; + justify-content: flex-start; + display: flex; + flex-direction: row; + margin: 10px; + padding: 15px; +} + +.container-profile .personal-information .profile-picture img{ + border-radius: 10%; + width: calc(20% - 50px); + height: auto; + margin: 10px; + margin-left: 5%; + border: 2px solid #000; +} + +.container-profile .personal-information .profile-picture .personal-title{ + display: flex; + justify-self: center; + + flex-direction: column; + justify-content: flex-start; + align-items: center; + margin-right: auto; + margin-left: 10%; +} +.container-profile .personal-information .profile-picture .personal-title h2{ + font-size: 2rem; + margin-bottom: 5px; + +} + +.container-profile .personal-information .basic-info{ + width: 100%; + + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: flex-start; + text-align: left; + +} +.container-profile .personal-information .basic-info h1{ + margin-left: 5%; +} + +.container-profile .personal-information .basic-info table,.container .personal-information .basic-info tbody{ + width: 100%; + border-collapse: collapse; + margin: 10px 0; + padding: 0 5%; +} + +.container-profile .personal-information .basic-info table tbody tr{ + width: 95%; + display: table-row; + justify-content: space-between; + align-items: center; + width: 100%; + padding: 10px 5%; + +} +.container-profile .personal-information .basic-info table tbody tr td{ + padding: 0 5%; + +} +.container-profile .personal-information .basic-info table tbody tr td button{ + background-color: transparent; + border: none; + color: rgba(0, 120, 62, 0.47); + font-size: 1.2rem; + margin-right: 5%; + margin-left: 15px; + cursor: pointer; +} + +.container-profile .personal-information .profile-picture #logout-button{ + background-color: red; + color: white; + width: 100px; + height: 45px; + margin: auto 5% auto 5%; + border: none; + font-size: 18px; + font-weight: semibold; + cursor: pointer; + align-self: center; + border-radius: 5px; + transition: all ease-in-out .5s; +} + +.container-profile .personal-information .profile-picture #logout-button:hover{ + background-color: hsl(0, 64%, 40%); + cursor: pointer; + transition: all ease-in-out .5s; +} + +.container-profile .edit-popUp{ + color: #0B1215; + position: absolute; + height: 30%; + width: 30%; + display: flex; + flex-direction: column; + background-color: white; + z-index: 200; + border-radius: 10px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + justify-content: center; + align-items: center; + box-shadow: 0 0px 50px 2px rgba(0, 0, 0, 0.5); +} +.container-profile .edit-popUp .confirm-buttons{ + display: flex; + flex-direction: row; + width: 100; + margin: 10% auto -5% auto; + +} +.container-profile .edit-popUp .confirm-buttons button{ + margin: 0 10px 0 10px; + border: none; + font-weight: 600; + height: 40px; + width: auto; + padding: auto 5px auto 5px; + color: white; + cursor: pointer; + border-radius: 5px; + transition: all ease-in-out .5s; +} +.container-profile .edit-popUp input{ + border-radius: 5px; + height: 30px; + width: 50%; + margin-top: 5px; + outline: none; + border: 1px solid black; + padding: 2px; +} diff --git a/src/pages/Profile/sample.jpg b/src/pages/Profile/sample.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0f9ff54733d56faadbc74791d831aa18423061dd GIT binary patch literal 10573 zcmb7qbxa&g^zGvAQrvY56e!XUcUasViu*!=;uMD>#fukrElXi>E$+Iw6j^jx911PG z{$BF(-oNk6Oft#M+%3FDoxQ0Af`okP-j|1pq+#*8nf;0C@l&4i47;?l?IA zrvC#x96UUHynlm$7@vfYfDoUQnv|V}o}HeWk&c_2l3i3-ga#-m#mmi4EzV5#KTc4v zu(AKGqQJwW;Gw6c=lTD}OCNv)8-N5L(NI_bs3a(8Bq%R~09pV56%FNo()~X`Lr2BH zL;+y^Gs+PIP*Kp(P|?vaFwwBkF#hccl>~r>PRcBRAxp-hW9=E9ib*agSInvl>7Tox zVDqAUt7j9D_KRKNQs1_uY5t!N8Wh0)`2T+bprE1w&@nLo+1N<{sQ(-PH-mox(3nXD z(8*Y21$C@h$vt1z0QhJq{}M(c0Z0Q#ZPT=b>>Hm3au?rdG)47MNVl)vkkw?wwS zY<6nugkxs4T1UfI&RvZKcnPBPLk_K|ucojvFl-*V)|RGNP>Q5@VY;fh^A94QYKJ#d z#0>*dSmP?}vPkc~_c^tG5TutVZ4K<~#9`N!xv9c?@_f|!QobhC_7&FQtBO+Pq3{AA z9AhK44QzP@LRgBbAT`G2{1SK+)D&EY*r%~DJb*j2 zVc)FP*CvLuuQz%f?-cw~1_0TG(WY>RUH+%aSgGq@wGY}p&MdOKlBbfzdlkyB2q%ho zj1nh=h+tn<+5ktFkUw(K1OC@{SZY0xjH8r00ul_^qFQJ&m=n> zG%n9pw}K7#&5`XcH^SS1Igk2_ z$seRPPE^8oc&Tl-4d1?!9Ei_%YaTcM>gK2gAJS$f$gA*Rp+)NL<|uO{nBD&@jy`lL zn~+j^pb_Cvdk^(x!6SGU!iPMG{GJyoWtnZI<+^p>CbJ-rxloqHkzf}j3%;(7rn z!e0RLqZf`_ZCbDT_Tm!cd>7TSe>IUp4=fL-6p+p7{6(P zSP$ zGXZ}IYDMubbHQW6LF%~G1!Z{(ZNl#A*ee`paI9t?{F0uYmh8`JMNOtom#N1spdASb zTnvO6vv`4E**8hFX1vfKr^d-FQD7*(`SVxj?mQJg#zC{?HAE4t(8Qh5%7=J++vQwK zrzN0X{H^3VmyX34ulrVU#Tv5L`#QdM`~>qs+m|N)3zeV@eYIBCaGydXheMF3dg-U| z@s2n3hxmhB{b{?;oIfh~T*9l91x3~$lrCR;Tc)^ESdkN}@POiIk-{1YSvwG^vLNjI zqtBuS0}C9EI;+{27Zh#bDjmb4959nb<;_3iKUJ8OhQb(mN3PakO?3XTyxVrOnfZ%m z_V(E{1(eZ~YZBtf_b}JNq5KCx27Rec; zI}S|7aGR3ZFE*3(OC>_YcLNQfWhR2Gw@oS7 zv>7CmX`Bb<-1hmVu=3_F?&8J?8nr9#wl0*gY;LqMC9`FYP;z98^Yhe9)WUG7KKljo zSl;Vb0RM6WUt{f>4N-IM!bfo@9#?4pB9$0^Kb%H<7UDlg2$>mnNuZLB*;5M+yCOl&(H;;uvGRj z;*z~3yh*iBYvLMEdeV5e%nM-SnQ39lY(S$i&2_~{A!{}$;Zw?0Xa2ZY>2f=)M@~eD zy&a$T8jKoAN(%ZWiYi$6M)Ks9V7h4>ZN$3@@Gfl;W%zdB>Bs$iT{aDi5H@@EQSVB7 zlNNBnDF!rt`b-^A+b#}!U*&`MNoLD$1PAsLuv+8Iv{3>^A!qm#bNC-AUs{>pO3%X2cy%5QRuhQEC`-#sHRnXg0f_*!`M(K zKQ?5%Zmq05m93>093B=kXZbtlc_w~@UoKo5O;BEcT3E<9(C~=e(QU+V0M+Ug{?ezI z>Zx>6<{y@wN-V|j1jjhIl)7|F@Kfj3?kMhyL-{X1_8ER!?yzq*Iov^IF%ncjupS@w zUW@PK2q*Dj+y8b&V`a@Dp&Av5H+ffc>Yqcr4&6^R%se+4r$nxU4bKTw=SYbl754f7 zE@qB#MTpmY+QN2Dx#4ochdRG{T42v2TC%gm0MN_uteI1%!hj(+2u0pak}llHNp|gB z*;{iaaXsM@^Kpb2(M?6Y`L45Y2Og;OAy%{jv~D{rZ^TC|Qm%1$&gJJ#fh82Z@wfjr zmp_4bj5dh!tfgLuBYpIv?zklPH$_hu>Zqj3?v4*T8 z^)&No^P&pN?L!t!gG}r#7VB#%#{nSla8W%SgUjVflumGcM*HeLQaa9ePx1x8zbP}% zq0CrrC^_8DH+b<*Duc33vtHxq-A#ka?9&yCNG-d3tJN*4@-PO)x$}I9Z$y8X_$*15 zalvNyiLOsNsY7hIdsj`fSNCKgte9uKh!7qk6}D`OPnmOjSIQwgpw5j4i4-Inh%WwW zh7K13NE8vGpu{3E+prhPE}5pE0uhFHA4tBspd)nM@HmtTV-^b*&E|kj1;0KsB@QHV zhOpXh6=kXSXXo#Ao3*N?c0!l}d;$Y?U-37r+W^)f2t`dE<#;tK6#O&COKR!WYU0m2 z=qH8RSo0D6Uvmz-6$BoyHPxN@GBEt}_dPFb>0BGIVtKQ?Y5LZ6W6|9IK84cMV(Jh+ zejQ_t756awBrkN48G$qrNFWZ|?(+jo9%H(>pq}(WX zEm#GAeNkf1N69J)l6-?6y6V^hCzF+|2IdIP7N=?YdOf@;&?PT_oT+1mc2BbnS%p1G zcOO=x@Y3-rO>qNNq3T)#eG!xMqkhOQNBz-9+=N`NqAxyMnYNdr^Xc?l|1tdln_Vx| zi}FaTets}~$2KD*nQ_O!tgME|^!AhM_OE!+!s-eF7+L${Vz83rQ~+`^wD=){USvD) z=ot1yq6gb*L1?J{Y0nG)74BhO+gn9({ifOQ^7(cV*&y4N;3Fp;(`W9xngJqdb>fgI zOkOCDWeuzh{n1VHw-EIp&7dJ6Y4F6$2XmvaV$R?v+|y6MTv~Z#=iHx+i81he)^^Xd z^v*~c2v<=P^_<_*iqV*GfEU+J!bb59l7F`EZPkcnX})W3eGGX`7wNDEY~txe(x}!U z&p5iX52H3YWQR(s$$!K*4gE}uUiQ5vRzxGf9#ynw4u8vn9lq5Jawdb`2u?RA>?w&B8)@adynL&D9k1^~~C>O7HsstR&00I>{h zkWp8iZR~nZ*}ho>g{vB4S>XJ#CzyKgV92e$in`>T_I zWh%s}hrE294Hg&+LeL#>`3wzt$id4US0 zZZfG&gEa6f_*WW>AGVrPo;{~S`1=;ORcTy`nLVNDf3tACJVGvuMKlHisz`z8_3m1C z#4%6EZX%>;w+s8{dSzYM0TbEN)K2KDV;#57zuB{sG;yz$(*>k^?UE-$GWH5npI!jv z=*Lwl&Ex927p-s2@tri`8Ueg=~_YE=e=06@6V~X4Bh{LP3)*x6jY>I)NIe-7+vC-d}JYrfuZl_JgtlYxRX&-XMWGZt{fGg^?)O6MD-F5 zdu5pEQhIqF*gnH8u^nI&Yv(%y!*(Zm3WJ@%VD9;i6e4einTqa!4Y-f+iuR!-p2a)Gh7_qGx#%(<*P>dT7zriGL|9w#s zYMSQLHA>)D*-$veyz|%ZuS>I!M6fq^vKvYx8wuo2r}jjV_-`?EoxEvc(`Zod1pqG# zX_*_jB}-me|E&%dI7;hsiHZo#6mAeJkIn)z1SI#V>2iC*$zfwg=EC*ZNP9WT}EnpUQb z&Fo?_7Oo{2VgMN$d^aTYpFZx+nsyJ>;#yaymiYC?BaCHy-LiPD36Z~0wW3s@;!R(B zr2c-sO`^T?{esDYn2l4Lg}&x~ zq|r!Pr->&G5Gq*>r`md@efsXcMBth}rPao~k?Akc#1GOTcLXhJX9hUW<3#dS28JT& zDESQ~Du+x4y>_=vla^^FD?~j-K=0E_qM&@8U_iTbuw# zJzZ);lz-XQYQQ|@!5;(H&r@v=RpQKwmh|^eog^ zH=;&KG*d_?KbPE~!rUl+K+(@sQlcWA6{qrr%+Y_iL}^mcu$VpS$)--Q;!24?b2r(57D zGa^b&)l|(nJSgNW;SH$r2&k>Amu3DejIQjcad%VoaIb~hX4|4bRVuT}?D@24dK%f{ zk2GhA^^;jc{G9qAJO(dQsmcP(0c6bDzrXS@jRjkrc7&A(SpCX$C^8=sggMwHxez3& ztd-je_17s(X*jm8wPh#QPWt9lBxc}|I{{e`y@9dlp31W|GPf0(OI298n5u(|TEYTu zX)I3XaVz?>fG!Wy#E~G9nd9Ru`;S$kXAjAadV;Shp?Ydf5i&cIzID+PqGxur)Y3=< zZ+R!Nk5m{49o#G2OD18cg%IvV6PZ>3r`qErZ$pFMJ~}tN0BFE}aEHofi`(Mdt+3H^ zG5OW*84&Y>+%%|X=uZX~e`4A_!7j{3(|eE`%#L=ydeDdiFXLBCOv%`Ig!adeU6Afv z@-Eot6h@5~K)z7E(v=em%7%CEG~{&YajNsP<-4vZcibpxmd=o`bdx=`ivVc#eUNmH zd`{>sNtdCq#hLWYaC3fcQuSiJ!+H=#-4AZ!%;rKuY{AK1Sk>lM|1$WCm;Ob_*B&Y0 zYAgP65Bcv{S|t*vb?OE~}LjmSK!0&oKD2ttfxnPu!KUIbXStMDAFOjGenN1K;f>rpk&5&u0b@6x7K}MBV@Om z;L|SXP<|hVuUlIqB6-4YmLn9WJ+Ap#Q<;QrnNVqC9$!7qRu4b5y;Np@pao{j+9Ke7 z8pe^KBs-{ot2vOF!s9WF^#aHRTIjUj)ch5X>?Y=B?S=h2%|DM{%PlEeHveuj{i?BH z=vsrtj{TXjNE+zRMx9t=BU$~66Nj7COv*mP=^??#B*R^9V?Gp5L2DqqvSzj24X=m2 zXxuvDcbXqyM7ZkILTGnWw4Tk@(w5`_ydhD2C)s;xkSVij7P=`_XnN0_p(+wT3^e0` zKmw)Sht+=Lk?eOc;#-UOvR{ij@XD6{X`!<0qZ#JK*oo0n|RU+GM@fqzZp zOxs@az7ub*sKL@1<}7#U#kqEbS*mrGH_<@5!&Gm_%10(_Q^|a~w$dNRw6NKK)Yo)7>YbtzQ2tUMH@Lr<#c6*=%w8a~r9(+oi9;fu0zsn->TD?$g%D~>M2e5ihW=zY!4RlV z_JEwy(ON|u7Dq1kUp0I5ems4*o;v1wyx|cRY9)!Hc4W9V8`XD?3IWWFFfPDd3EB$o z6#-rRUT;yoykUehy8{payq15(S7@!%_KUcCUhc2)9}Hb$Zy&P%*dkgwsZrd_amUiV zwxlxu46P6?6lMfJG1rx!*4yfgT)G3X1W$^`!`8i_Pli9qm>X`TGWf~2dJI1HUm3S8 zf$q{P=_E$RWS`AM_M~aeM!_qgOQZL>_l*xdT@sz__`S!2b!t(G+0IE?tZT(31N>f& z>%W)mC$cW7b217h=wlC*+lpItAF&NG9y_x1FmHJRr~Qrp%k0uZF~2JPe!OL zmd8+(b84!>c~=qCaLH)r=V6;3CHv=!y+2Um_JsH#^YJ#8J)#@FZAz&ONdJDW$|?tB z51g9^9p9cFF@BTm1x^w+X~P&K4GOb8Fj%IKI+N8yXK<+V&eJkjdI6AO(d_3BmTt6; zNM+Dwo>>CS3uTTUMkZpbeuvO}%}aLVDjkEdI{ne}JW{_@4;+mj7D!o&Y?SL?!u`wyVx*H?HjNlY~d(&3E42r3EKt zioST13f0I)KdOF~2#dUUdl~0KSQ`|9wGq$cGGt`F__L8CPXrvv6i;iaH)vSu$%8L4 z-2SUN)#Bm`#AMtp1#1XZ&5F#HzWWV$^f!_&2aa$EKBr*UzBNZS8|4lMoe6k_7`lh5 z#toi8|NJClRd+XC)nRCwQ`}2`M9*cTXz>`LR;Q0vf=Q`GxHp;7JSdRX} z2I&|8@irF9)arl!oEdav7BBham{OzFwiB#H!R)G%*Gd`cBg(q#|16Y$UZItWeWTq7 zpqmkj{YKe7!8l?dZxT?)1iYc zSqA9;XaI2j7GEOxkL$|vvO#A8Efp|GFm=PXP6~WCav?~mF&P9!R+F?VEs@+Zifycn zwWhjkuDen5v2>*NOmcKfQ+}iQ&s!{`kbkBnbwThwmXM2{6v3`UYkd;VJ^iu%&wgM0 zsTj1U-t3F>YyC5z3?X=2Af7u|WRo(Z}Tvmp>kdZLEJ)iBh??A*AT@WRRYF ztwra)51u1*d142d+{Rmkd>*D#>i8f9;@<&ms@Om3LFUKD~u=m;77Hn;g+Kpx{~g!SB(-{Kuu|L_N8lt5QG{mFh^go9sSg zw711k_F8imA)mHv;JmrTPE(@%&d*R-*aKA^#I1>OGgM@o!8Iv_e0lGOSI?>p!_ICL z{L+~%ewMJ%SH;Y}NGnBa#wFonR}6e;=85*vNV>-LsPf;%nyK>x3dfh+Y>==^pyHKi z;|t&}*YZ$vLXOpRr50+Ty!brXhp2)#w^w|WE%%LdiF0=u7`KTYHy8l}f;&K)+p zbFu=@{_&xWc`an~@cJ1yiN8SF$oOQBu9dR@THw!;rE9)p8+8T5Om8{IZ%tVnzibm$ zuOQ@Kgz82cYVv>C((mr7{1XI0lK1#lgC52(+9Bqs{JgeERL=JD?2UgctL^}H^?WMaZpIsq? z&Msa6)16(SS57fLWfM(oibg(!`QiDAAuunqcl~Ocu5~0}Aad7LLb-0K_Q9!@&)iV-EM5loY&i2(cNF}>+S=NdfwuPAWl zP;u%EanI>(8n4a8#7Z5Lm~g~)V1LsdG7CTej!&_o7N_2QExYi;j7_qYb*Qzs-IAkm zJAft?4NVlI4~3sX^zC*UaJd35`K{JZX(yuGK^SeVQCy_LbsJbF8912@y}n?CbwAG< zBb^U-r0YrWbJst}I09zGYM1p_p@>>-R1~ahf$;YVb9Pjeh%8w%2GBM~$4@t9;_!i`KG zkb$#k39<$bv-GRW2;z^i29V06)7Q%0>F#fx_}bB1Vl0sch^0*asYw8(GHW?mDuDTY zOLq1xhfa*4U{c;&qAR1k4+i)>JyqgP$k&Gp8jmP!vKujv0$Qf$fxb(V~EnYXtJItqa}Dr;*ctl-3n zj6WI|@1a0fE_)dTBoTxhdgJ=DJKbhYq~so(m@wZIlzN%iUD8hH+?J(f=oB(_Yo3%e z>S4|s`6-oejkZ1oGt~#{J2G@HwCI*DLFCaeM5z%BeVyQj9V4n7lk#bd#5j*$m`_ye zr?x22Jju#kLv(3D5XRe3!1$-UZmGL0e>}We?=R5q1#oFlNd;BYO?&MCc>hnr4K7ka z1(39Ok7A>vNXHc=-ZA1H^ALOBZjAS{7QAZ+2bV?w00>;rUSjQt_^4DyA``uW(w~Ap zGzbR~<9HdKDgJsm{w$^D_W=OiGRS~(S$QYj4TG4|gC{<58SDHmBk6ov79V>7;N8mh z_cfIm8g{hR5!w{l4Qfe$zsEb$V!|8&L~Gy?i@ZmrZ=z*EYPVwicr(HMHLBU{zaoq5 zGnOiMc*ml3Pp;=BgpnxI7YT^b{jbPHx2_DaGP)%iTXo7hX$7EEqnCF`9YUj5E5G{o zOwknIB)ar_G)WRT!SM7thEB6+-Ro0LCaktnM;EQr+-9;*K8Iw+C2+#bP|Zc2S}c|n zJqU*58F-C1RjwKHSp}Vd2MsKDnO)eoa8d8Kde`b#X=bSJ+jLfG8eyIE@8z~Wm@Xuk z_Wj+Po09B$H*U<3(0beFl`RHNjSlo)bne z>H{3pezpnqSTUfDy(d$SEd^x&sn9Q$7N^&i=nCDq*1#GDh1V+GUAs}y=TP)0 z7={Yi=bm@dNSqD!8R%8zhE~20Zb+CH)Or)=CUj+@loqP`eZ0|2ab2UOjo^b8u*d)J z>m#P;8R1fte_s(aHDG`fKkF)Y_5=V9^7vfx*xGm3yv4`Y)xGtV6MA)lT? z>(0pUK3FT42(qm((YKrdQcrG>{H-`X!;On#qPq0B7>O zE#FMBXmxA6r2RlnMGWAu?Y5=UM$h4}&1X$T*Zxj_Z!3gN-UFt}SqAWJ63jk6JO9;+q^TSPU+cy`&0=Lta85gsC9-_Jmo6{tcQ4{x89@74TG3#IQRCelFnlcrf3?2rHb0+1Vf nYOt?ldQfesBcI@B`p)^ZzSZ)6Zzc5^elI!xkA*QgzO4Q)Yqc@U literal 0 HcmV?d00001 diff --git a/src/pages/Profile/style.css b/src/pages/Profile/style.css deleted file mode 100644 index d59f6f6..0000000 --- a/src/pages/Profile/style.css +++ /dev/null @@ -1,154 +0,0 @@ -.profile-title { - align-self: center; - top: -1.85rem; - font-size: 2rem; - font-weight: 850; - color: white; - background-color: rgb(48, 54, 61); - border-radius: 1.5rem; - width: 20rem; - height: 3.5rem; - text-align: center; - line-height: 3.5rem; - border: 2px solid #1BE985; -} - -.program-card { - width: 50%; - display: flex; - justify-content: space-around; - height: fit-content; - align-self: center; - background-color: #263238; - margin-bottom: 2rem; - - border-radius: 2rem; - - box-shadow: 0 0 0 1px #000, 0 30px 30px rgba(0, 0, 0, 0.08), - 0 15px 15px rgba(0, 0, 0, 0.08), 0 10px 8px rgba(0, 0, 0.08), - 0 4px 4px rgba(0, 0, 0, 0.08), 0 2px 2px rgba(0, 0, 0, 0.08); - padding: 0.5rem; - border: 1px solid black; -} - -.profile-info-container{ - margin-top: 2rem; - display: flex; - flex-direction: column; - position: relative; - align-items: center; - justify-content: space-around; - width: 100%; - padding-top: 3rem; - border-radius: 2.5rem; - background-color: #24292e; - box-shadow: 0 0 0 0.5px #000, 0 30px 30px rgba(0, 0, 0, 0.08), - 0 15px 15px rgba(0, 0, 0, 0.08), 0 10px 8px rgba(0, 0, 0.08), - 0 4px 4px rgba(0, 0, 0, 0.08), 0 2px 2px rgba(0, 0, 0, 0.08); - - border: 2px solid #1BE985; - -} - -.program-container{ - display: flex; - flex-direction: column; - align-items: center; - justify-content: flex-start; - width: 100%; - height: 90%; - max-height: 25rem; - overflow-y: auto; - padding-top: 1rem; - - border-radius: 2.5rem; -} - -.program-container::-webkit-scrollbar { - width: 0.5rem; - height: 70%; -} - -.program-container::-webkit-scrollbar-track { - - border-radius: 0.5rem; - background-color: #e7e7e7; - border: 1px solid #cacaca; - margin-bottom: 2.5rem; -} - -.program-container::-webkit-scrollbar-thumb { - border-radius: 0.5rem; - background-color: #1BE985; - border: 1px solid #1b1f24; - -} - -.delete-image{ - width: 2rem; - height: 2rem; - align-self: center; - cursor: pointer; -} -.delete-image:hover{ - transition: 0.3s; - transform: scale(1.01); - filter: invert(20%) sepia(32%) saturate(2127%) hue-rotate(90deg) brightness(100%) contrast(100%); -} - -.buttons-container { - align-self: center; - display: flex; - justify-content: space-around; - margin-top: 1rem; - width: 30%; -} - -.profile-button { - width: fit-content; - appearance: none; - background-color: #15c871; - border: 2px solid #1A1A1A; - border-radius: 1.4rem; - color: #FFFFFF; - cursor: pointer; - font-size: 1rem; - font-weight: 600; - min-height: 60px; - padding: 1rem 24px; - text-align: center; - text-decoration: none; - transition: all 300ms cubic-bezier(.23, 1, 0.32, 1); - touch-action: manipulation; - will-change: transform; - - box-shadow: 0 0 0 1px #000, 0 30px 30px rgba(0, 0, 0, 0.07), - 0 15px 15px rgba(0, 0, 0, 0.06), 0 10px 8px rgba(0, 0, 0, 0.05), - 0 4px 4px rgba(0, 0, 0, 0.04), 0 2px 2px rgba(0, 0, 0, 0.03); -} - -.profile-button:hover { - box-shadow: rgba(0, 0, 0, 0.25) 0 8px 15px; - transform: translateY(-2px); -} - -.profile-button:active { - box-shadow: none; - transform: translateY(0); -} - -.profile-container{ - display: flex; - flex-direction: column; - width: 75%; - height: 70%; - justify-content: center; - align-self: center; - -} -.profile-container p{ - text-align: left; - font-size: 1.5rem; - font-weight: 600; - margin: 0.5rem 0; -} \ No newline at end of file diff --git a/src/pages/Register/index.jsx b/src/pages/Register/index.jsx index 3f238ab..c4aa597 100644 --- a/src/pages/Register/index.jsx +++ b/src/pages/Register/index.jsx @@ -1,9 +1,9 @@ import React from 'react' import {AuthForm} from '../../components/' - +import SignUpForm from '../../components/signUpForm' const Register = ({updateCurrentUser}) => { return ( - + ) } From c39f0711fdc09852ec8f1444dc5e44a1dc545a48 Mon Sep 17 00:00:00 2001 From: nejem Eddine Mekentichi <83135662+Nejmeddine-Mek@users.noreply.github.com> Date: Sun, 27 Apr 2025 22:43:16 +0100 Subject: [PATCH 11/12] fixed labels issue, wokring on profile and navbar currently --- src/assembler/Assembler.js | 2 +- src/components/Exercices/Level1/level1.jsx | 2 +- src/components/Exercices/Level2/level2.jsx | 2 +- src/components/Exercices/Level3/level3.jsx | 2 +- src/components/Exercices/Level4/level4.jsx | 2 +- src/components/NavBar/index.jsx | 48 +++++++++++++++------- src/components/NavBar/style.css | 6 +-- src/components/loginForm/index.jsx | 8 ++-- src/components/signUpForm/index.jsx | 5 ++- src/pages/ExamplesPage/index.jsx | 2 +- src/pages/ExercicesPage/index.jsx | 2 +- src/pages/Hero/index.jsx | 3 +- src/pages/Ide/index.jsx | 2 +- src/pages/LearnPage/index.jsx | 2 +- src/pages/Profile/index.jsx | 2 +- 15 files changed, 56 insertions(+), 34 deletions(-) diff --git a/src/assembler/Assembler.js b/src/assembler/Assembler.js index f803383..5bbd173 100644 --- a/src/assembler/Assembler.js +++ b/src/assembler/Assembler.js @@ -883,7 +883,7 @@ export class Assembler{ // two pass first pass stays as it is with adding a delimater at each label and then re apply the semantic analysis for the labels and then reassemble the code if ( Errorcalm.SemanticError.length === 0 ) { for (let index = 0; index < toassmb.length; index++) { - if (index >= lines) { + if (index >= lines && Assembler.Labellist.labeltype) { Assembler.Labellist[i].address = ipTrack; i++; if (i < Assembler.Labellist.length) { diff --git a/src/components/Exercices/Level1/level1.jsx b/src/components/Exercices/Level1/level1.jsx index 98d3636..469d0ed 100755 --- a/src/components/Exercices/Level1/level1.jsx +++ b/src/components/Exercices/Level1/level1.jsx @@ -173,7 +173,7 @@ function Level1() { return ( <> - +
diff --git a/src/components/Exercices/Level2/level2.jsx b/src/components/Exercices/Level2/level2.jsx index f4bc83b..1f91bea 100755 --- a/src/components/Exercices/Level2/level2.jsx +++ b/src/components/Exercices/Level2/level2.jsx @@ -231,7 +231,7 @@ function Level2() { return (
- +
diff --git a/src/components/Exercices/Level3/level3.jsx b/src/components/Exercices/Level3/level3.jsx index 33bcfcd..09584f2 100755 --- a/src/components/Exercices/Level3/level3.jsx +++ b/src/components/Exercices/Level3/level3.jsx @@ -116,7 +116,7 @@ function Level3() { return (
- +
diff --git a/src/components/Exercices/Level4/level4.jsx b/src/components/Exercices/Level4/level4.jsx index db4be51..e9fe740 100755 --- a/src/components/Exercices/Level4/level4.jsx +++ b/src/components/Exercices/Level4/level4.jsx @@ -115,7 +115,7 @@ function Level4() { }; return (
- +
diff --git a/src/components/NavBar/index.jsx b/src/components/NavBar/index.jsx index 1e22ba0..13267b1 100644 --- a/src/components/NavBar/index.jsx +++ b/src/components/NavBar/index.jsx @@ -1,7 +1,8 @@ import { Link , useNavigate} from "react-router-dom"; import logo from "../../assets/Group16.png" +import pic from "../../pages/Profile/sample.jpg" import "./style.css"; -const NavBar = () => { +const NavBar = (props) => { // we need to be redirected to signup / login forms or profile on click const navigate = useNavigate(); @@ -12,20 +13,39 @@ const NavBar = () => { const handleSignUpClick = () => { navigate('/register'); } - - return ( + + const handleProfile = () => { + navigate("/profile") + } + if(!props.isLoggedIn){ + return ( + + + ) + } else { + return ( - - ); + + ) + } + } export default NavBar; \ No newline at end of file diff --git a/src/components/NavBar/style.css b/src/components/NavBar/style.css index 03c9f3f..2a06e47 100644 --- a/src/components/NavBar/style.css +++ b/src/components/NavBar/style.css @@ -43,8 +43,8 @@ body{ display: flex; flex-direction: row; list-style-type: none; - margin: 5%; - padding: 5%; + margin: 1%; + padding: 1%; gap: 20px; } @@ -137,4 +137,4 @@ body{ .navbar-container .login:hover{ cursor: pointer; -} \ No newline at end of file +} diff --git a/src/components/loginForm/index.jsx b/src/components/loginForm/index.jsx index fbcbb65..9c637ba 100644 --- a/src/components/loginForm/index.jsx +++ b/src/components/loginForm/index.jsx @@ -1,4 +1,4 @@ -import Navbar from "../NavBar/index.jsx" +import NavBar from "../NavBar/index.jsx" import "./login.css" import { useState } from "react" import { useNavigate } from "react-router-dom" @@ -60,8 +60,8 @@ function LoginForm(){ //get result, store token in local storage, then redirect to profile //then store in local storage data.modified ??= false - localStorage.setItem("user", JSON.stringify(data)) - + localStorage.setItem("user", JSON.stringify({data: data, isLoggedIn: true})) + localStorage.setItem("loginState", JSON.stringify(true)) //navigate to profile page or wherever navigate("/profile") } @@ -69,7 +69,7 @@ function LoginForm(){ return( <> - +

Login

diff --git a/src/components/signUpForm/index.jsx b/src/components/signUpForm/index.jsx index 56baf35..0a86a43 100644 --- a/src/components/signUpForm/index.jsx +++ b/src/components/signUpForm/index.jsx @@ -1,6 +1,6 @@ import isEmail from "validator/lib/isEmail" import "./signup.css" -import Navbar from "../NavBar/index.jsx" +import NavBar from "../NavBar/index.jsx" import { useState } from "react" import { use } from "react" function SignUpForm(){ @@ -79,6 +79,7 @@ function SignUpForm(){ genData.modified ??= false localStorage.setItem("user", JSON.stringify(genData)) + localStorage.setItem("loginState", JSON.stringify(true)) // verify email //after verification is done, redirect to profile page @@ -88,7 +89,7 @@ function SignUpForm(){ return ( <> - +

Sign Up

diff --git a/src/pages/ExamplesPage/index.jsx b/src/pages/ExamplesPage/index.jsx index cfb1de0..b0f4fcc 100644 --- a/src/pages/ExamplesPage/index.jsx +++ b/src/pages/ExamplesPage/index.jsx @@ -36,7 +36,7 @@ const ExamplesPage = () => { return ( <> - +
diff --git a/src/pages/ExercicesPage/index.jsx b/src/pages/ExercicesPage/index.jsx index 1432396..2ebd4bf 100644 --- a/src/pages/ExercicesPage/index.jsx +++ b/src/pages/ExercicesPage/index.jsx @@ -14,7 +14,7 @@ import Bot from "../../components/ChatBot"; function ExercicesPage(props) { return ( <> - + {/*
</main> */} diff --git a/src/pages/Hero/index.jsx b/src/pages/Hero/index.jsx index b6fe03c..76bdd4c 100644 --- a/src/pages/Hero/index.jsx +++ b/src/pages/Hero/index.jsx @@ -25,6 +25,7 @@ import { useNavigate } from "react-router-dom"; const Hero = () => { + console.log(JSON.parse(localStorage.getItem("loginState")) || false) const Part1 = () => { return ( <section className="slogan-container"> @@ -222,7 +223,7 @@ const Hero = () => { }) let navigate = useNavigate(); return < > - <NavBar/> + <NavBar isLoggedIn={true}/> <main id="get-started-container" style={{position: "relative", height: "10%"}}> <Title/> diff --git a/src/pages/Ide/index.jsx b/src/pages/Ide/index.jsx index 5076d8a..1942f08 100644 --- a/src/pages/Ide/index.jsx +++ b/src/pages/Ide/index.jsx @@ -254,7 +254,7 @@ const Ide = ({currentUser})=>{ <> {!simul && <> - <NavBar/> + <NavBar isLoggedIn={true}/> <div style={{display:"flex"}} className="ide_container"> <div className='codeContainer' id="cont"> diff --git a/src/pages/LearnPage/index.jsx b/src/pages/LearnPage/index.jsx index 0eef369..550c8f2 100644 --- a/src/pages/LearnPage/index.jsx +++ b/src/pages/LearnPage/index.jsx @@ -17,7 +17,7 @@ import Bot from "../../components/ChatBot"; function LearnPage() { return ( <> - <NavBar/> + <NavBar /> <img src={LearnTitle} className="learnTitle" alt="" /> <div className="globalContainerLearn"> diff --git a/src/pages/Profile/index.jsx b/src/pages/Profile/index.jsx index 4818547..7464ec2 100644 --- a/src/pages/Profile/index.jsx +++ b/src/pages/Profile/index.jsx @@ -7,7 +7,7 @@ import { red } from "@mui/material/colors" function Profile(){ const user = localStorage.getItem('user') const {data} = JSON.parse(user) - + const [hoveredOverConfirm,setHoveredOverConfirm] = useState(false) const [hoveredOverCancel,setHoveredOverCancel] = useState(false) const Hover = (e) => { From f315c981089a8f376058a2978d0229fb0061a300 Mon Sep 17 00:00:00 2001 From: redouane-bensaci <nm_bensaci@esi.dz> Date: Sun, 27 Apr 2025 23:50:25 +0100 Subject: [PATCH 12/12] finall --- src/assembler/Assembler.js | 2 +- src/components/signUpForm/index.jsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/assembler/Assembler.js b/src/assembler/Assembler.js index 5bbd173..7046c3c 100644 --- a/src/assembler/Assembler.js +++ b/src/assembler/Assembler.js @@ -894,7 +894,7 @@ export class Assembler{ } ipTrack = ipTrack+(Assembler.assemble(toassmb[index]).length/2) } - SemanticAnalysis.labeltype = false; + SemanticAnalysis.labeling = false; output = new Assembler(input2.code) // if semantic analysis returns any error we return it from here if(output.input?.error){ diff --git a/src/components/signUpForm/index.jsx b/src/components/signUpForm/index.jsx index 0a86a43..3e63172 100644 --- a/src/components/signUpForm/index.jsx +++ b/src/components/signUpForm/index.jsx @@ -1,4 +1,3 @@ -import isEmail from "validator/lib/isEmail" import "./signup.css" import NavBar from "../NavBar/index.jsx" import { useState } from "react"