Initial commit
This commit is contained in:
		
						commit
						b7defdf5d8
					
				
					 35 changed files with 2343 additions and 0 deletions
				
			
		
							
								
								
									
										3
									
								
								Home/Compiler/.babelrc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Home/Compiler/.babelrc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
{
 | 
			
		||||
  "presets": ["@babel/preset-env"]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								Home/Compiler/.npmrc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								Home/Compiler/.npmrc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
package-lock=false
 | 
			
		||||
							
								
								
									
										190
									
								
								Home/Compiler/.stylelintrc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								Home/Compiler/.stylelintrc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,190 @@
 | 
			
		|||
{
 | 
			
		||||
  "extends": "/usr/local/lib/node_modules/stylelint-config-standard",
 | 
			
		||||
  "plugins": [
 | 
			
		||||
    "/usr/local/lib/node_modules/stylelint-order"
 | 
			
		||||
  ],
 | 
			
		||||
  "rules": {
 | 
			
		||||
    "at-rule-no-vendor-prefix": true,
 | 
			
		||||
    "media-feature-name-no-vendor-prefix": true,
 | 
			
		||||
    "property-no-vendor-prefix": true,
 | 
			
		||||
    "selector-no-vendor-prefix": true,
 | 
			
		||||
    "value-no-vendor-prefix": true,
 | 
			
		||||
    "order/properties-order": [
 | 
			
		||||
      [
 | 
			
		||||
        "font",
 | 
			
		||||
        "font-family",
 | 
			
		||||
        "font-size",
 | 
			
		||||
        "font-weight",
 | 
			
		||||
        "font-style",
 | 
			
		||||
        "font-variant",
 | 
			
		||||
        "font-size-adjust",
 | 
			
		||||
        "font-stretch",
 | 
			
		||||
        "font-effect",
 | 
			
		||||
        "font-emphasize",
 | 
			
		||||
        "font-emphasize-position",
 | 
			
		||||
        "font-emphasize-style",
 | 
			
		||||
        "font-smooth",
 | 
			
		||||
        "line-height",
 | 
			
		||||
        "position",
 | 
			
		||||
        "z-index",
 | 
			
		||||
        "top",
 | 
			
		||||
        "right",
 | 
			
		||||
        "bottom",
 | 
			
		||||
        "left",
 | 
			
		||||
        "display",
 | 
			
		||||
        "visibility",
 | 
			
		||||
        "float",
 | 
			
		||||
        "clear",
 | 
			
		||||
        "overflow",
 | 
			
		||||
        "overflow-x",
 | 
			
		||||
        "overflow-y",
 | 
			
		||||
        "clip",
 | 
			
		||||
        "zoom",
 | 
			
		||||
        "align-content",
 | 
			
		||||
        "align-items",
 | 
			
		||||
        "align-self",
 | 
			
		||||
        "flex",
 | 
			
		||||
        "flex-flow",
 | 
			
		||||
        "flex-basis",
 | 
			
		||||
        "flex-direction",
 | 
			
		||||
        "flex-grow",
 | 
			
		||||
        "flex-shrink",
 | 
			
		||||
        "flex-wrap",
 | 
			
		||||
        "justify-content",
 | 
			
		||||
        "order",
 | 
			
		||||
        "box-sizing",
 | 
			
		||||
        "width",
 | 
			
		||||
        "min-width",
 | 
			
		||||
        "max-width",
 | 
			
		||||
        "height",
 | 
			
		||||
        "min-height",
 | 
			
		||||
        "max-height",
 | 
			
		||||
        "margin",
 | 
			
		||||
        "margin-top",
 | 
			
		||||
        "margin-right",
 | 
			
		||||
        "margin-bottom",
 | 
			
		||||
        "margin-left",
 | 
			
		||||
        "padding",
 | 
			
		||||
        "padding-top",
 | 
			
		||||
        "padding-right",
 | 
			
		||||
        "padding-bottom",
 | 
			
		||||
        "padding-left",
 | 
			
		||||
        "table-layout",
 | 
			
		||||
        "empty-cells",
 | 
			
		||||
        "caption-side",
 | 
			
		||||
        "border-spacing",
 | 
			
		||||
        "border-collapse",
 | 
			
		||||
        "list-style",
 | 
			
		||||
        "list-style-position",
 | 
			
		||||
        "list-style-type",
 | 
			
		||||
        "list-style-image",
 | 
			
		||||
        "content",
 | 
			
		||||
        "quotes",
 | 
			
		||||
        "counter-reset",
 | 
			
		||||
        "counter-increment",
 | 
			
		||||
        "resize",
 | 
			
		||||
        "cursor",
 | 
			
		||||
        "user-select",
 | 
			
		||||
        "nav-index",
 | 
			
		||||
        "nav-up",
 | 
			
		||||
        "nav-right",
 | 
			
		||||
        "nav-down",
 | 
			
		||||
        "nav-left",
 | 
			
		||||
        "transition",
 | 
			
		||||
        "transition-delay",
 | 
			
		||||
        "transition-timing-function",
 | 
			
		||||
        "transition-duration",
 | 
			
		||||
        "transition-property",
 | 
			
		||||
        "transform",
 | 
			
		||||
        "transform-origin",
 | 
			
		||||
        "animation",
 | 
			
		||||
        "animation-name",
 | 
			
		||||
        "animation-duration",
 | 
			
		||||
        "animation-play-state",
 | 
			
		||||
        "animation-timing-function",
 | 
			
		||||
        "animation-delay",
 | 
			
		||||
        "animation-iteration-count",
 | 
			
		||||
        "animation-direction",
 | 
			
		||||
        "text-align",
 | 
			
		||||
        "text-align-last",
 | 
			
		||||
        "vertical-align",
 | 
			
		||||
        "white-space",
 | 
			
		||||
        "text-decoration",
 | 
			
		||||
        "text-emphasis",
 | 
			
		||||
        "text-emphasis-color",
 | 
			
		||||
        "text-emphasis-style",
 | 
			
		||||
        "text-emphasis-position",
 | 
			
		||||
        "text-indent",
 | 
			
		||||
        "text-justify",
 | 
			
		||||
        "letter-spacing",
 | 
			
		||||
        "word-spacing",
 | 
			
		||||
        "text-outline",
 | 
			
		||||
        "text-transform",
 | 
			
		||||
        "text-wrap",
 | 
			
		||||
        "text-overflow",
 | 
			
		||||
        "text-overflow-ellipsis",
 | 
			
		||||
        "text-overflow-mode",
 | 
			
		||||
        "word-wrap",
 | 
			
		||||
        "word-break",
 | 
			
		||||
        "tab-size",
 | 
			
		||||
        "hyphens",
 | 
			
		||||
        "pointer-events",
 | 
			
		||||
        "opacity",
 | 
			
		||||
        "color",
 | 
			
		||||
        "border",
 | 
			
		||||
        "border-width",
 | 
			
		||||
        "border-style",
 | 
			
		||||
        "border-color",
 | 
			
		||||
        "border-top",
 | 
			
		||||
        "border-top-width",
 | 
			
		||||
        "border-top-style",
 | 
			
		||||
        "border-top-color",
 | 
			
		||||
        "border-right",
 | 
			
		||||
        "border-right-width",
 | 
			
		||||
        "border-right-style",
 | 
			
		||||
        "border-right-color",
 | 
			
		||||
        "border-bottom",
 | 
			
		||||
        "border-bottom-width",
 | 
			
		||||
        "border-bottom-style",
 | 
			
		||||
        "border-bottom-color",
 | 
			
		||||
        "border-left",
 | 
			
		||||
        "border-left-width",
 | 
			
		||||
        "border-left-style",
 | 
			
		||||
        "border-left-color",
 | 
			
		||||
        "border-radius",
 | 
			
		||||
        "border-top-left-radius",
 | 
			
		||||
        "border-top-right-radius",
 | 
			
		||||
        "border-bottom-right-radius",
 | 
			
		||||
        "border-bottom-left-radius",
 | 
			
		||||
        "border-image",
 | 
			
		||||
        "border-image-source",
 | 
			
		||||
        "border-image-slice",
 | 
			
		||||
        "border-image-width",
 | 
			
		||||
        "border-image-outset",
 | 
			
		||||
        "border-image-repeat",
 | 
			
		||||
        "outline",
 | 
			
		||||
        "outline-width",
 | 
			
		||||
        "outline-style",
 | 
			
		||||
        "outline-color",
 | 
			
		||||
        "outline-offset",
 | 
			
		||||
        "background",
 | 
			
		||||
        "background-color",
 | 
			
		||||
        "background-image",
 | 
			
		||||
        "background-repeat",
 | 
			
		||||
        "background-attachment",
 | 
			
		||||
        "background-position",
 | 
			
		||||
        "background-position-x",
 | 
			
		||||
        "background-position-y",
 | 
			
		||||
        "background-clip",
 | 
			
		||||
        "background-origin",
 | 
			
		||||
        "background-size",
 | 
			
		||||
        "box-decoration-break",
 | 
			
		||||
        "box-shadow",
 | 
			
		||||
        "text-shadow"
 | 
			
		||||
      ],
 | 
			
		||||
      {
 | 
			
		||||
        "unspecified": "bottomAlphabetical"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								Home/Compiler/LICENSE
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Home/Compiler/LICENSE
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2011-2019 Twitter, Inc.
 | 
			
		||||
Copyright (c) 2011-2019 The Bootstrap Authors
 | 
			
		||||
Copyright (C) 2017 by Marijn Haverbeke <marijnh@gmail.com> and others
 | 
			
		||||
Copyright (c) 2013-present, Yuxi (Evan) You
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in
 | 
			
		||||
all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
							
								
								
									
										22
									
								
								Home/Compiler/README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Home/Compiler/README.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
# Requirements
 | 
			
		||||
 | 
			
		||||
- node.js
 | 
			
		||||
- npm
 | 
			
		||||
 | 
			
		||||
# Install Dependencies
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ npm install
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
# Generate main.js
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ npm run build
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
# Watch for changes
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ npm run watch
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										75
									
								
								Home/Compiler/index.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								Home/Compiler/index.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8">
 | 
			
		||||
  <title>Assignment</title>
 | 
			
		||||
  <link rel="stylesheet" href="lib/bootstrap.min.css">
 | 
			
		||||
  <link rel="stylesheet" href="lib/codemirror.min.css">
 | 
			
		||||
  <link rel="stylesheet" href="main.css">
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <div id="root" class="container">
 | 
			
		||||
    <h1>Lexical, Syntax & Semantic Analysis</h1>
 | 
			
		||||
    <dl class="row mt-5">
 | 
			
		||||
      <dt class="col-sm-2">Requirements: </dt>
 | 
			
		||||
      <dd class="col-sm-10">
 | 
			
		||||
      <pre>
 | 
			
		||||
# 保留字或運算子:begin, for, end, if, then, else, while, int
 | 
			
		||||
# 運算子:+, -, *, /, =
 | 
			
		||||
# 判斷子:<, >, <=, >=, ==, and, or
 | 
			
		||||
# 若有詞法或語法錯誤,請印出並說明
 | 
			
		||||
# 請印出所有變數最後的狀態
 | 
			
		||||
# 自定義文法,使得以下範例成立:
 | 
			
		||||
 | 
			
		||||
begin
 | 
			
		||||
    int x=0, zzz=5;
 | 
			
		||||
    int i, j=1;
 | 
			
		||||
    # 進行迴圈
 | 
			
		||||
    for, i=1, i<=50, j; # j爲i每次遞增的值
 | 
			
		||||
        x=x+1;
 | 
			
		||||
    end
 | 
			
		||||
    if ((x>5) and (j<=8)) then
 | 
			
		||||
        x=1;
 | 
			
		||||
    else
 | 
			
		||||
        for, i=1, i<=50, j+1;
 | 
			
		||||
            x=x+1;
 | 
			
		||||
        end
 | 
			
		||||
        while (i<11)
 | 
			
		||||
            yy=x;
 | 
			
		||||
            i=i+1;
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
      </pre>
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt class="col-sm-2">Source Code: </dt>
 | 
			
		||||
      <dd class="col-sm-10">
 | 
			
		||||
        <div class="custom-file">
 | 
			
		||||
          <input type="file" id="file" class="custom-file-input" @change="fileHandler">
 | 
			
		||||
          <label class="custom-file-label" for="file">{{ file ? file.name : 'Choose file' }}</label>
 | 
			
		||||
          <button type="button" class="btn btn-secondary" @click="fileHandler">Reload</button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div id="editor" class="editor"></div>
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt class="col-sm-2"></dt>
 | 
			
		||||
      <dd class="col-sm-10">
 | 
			
		||||
        <button type="button" class="btn btn-info" @click="lexer">Lex</button>
 | 
			
		||||
        <button type="button" class="btn btn-info" @click="parser">Parse</button>
 | 
			
		||||
        <button type="button" class="btn btn-primary" @click="run">Run</button>
 | 
			
		||||
        <button type="button" class="btn btn-secondary" @click="reset">Clear</button>
 | 
			
		||||
      </dd>
 | 
			
		||||
      <hr>
 | 
			
		||||
      <dt class="col-sm-2">Console: </dt>
 | 
			
		||||
      <dd class="col-sm-10">
 | 
			
		||||
        <pre class="error" v-if="error" v-text="error"></pre>
 | 
			
		||||
        <pre v-if="!error && ids.length" v-for="(v, i) in ids">{{ v }}: {{ vars[i] }}</pre>
 | 
			
		||||
        <p v-if="!error && lex.length" v-for="(l, i) in lex">{{ l }}</p>
 | 
			
		||||
        <pre v-if="!error && json" v-text="json"></pre>
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
  </div>
 | 
			
		||||
  <script src="lib/codemirror.min.js"></script>
 | 
			
		||||
  <script src="lib/vue-2.6.0.min.js"></script>
 | 
			
		||||
  <script src="main.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										7
									
								
								Home/Compiler/lib/bootstrap.min.css
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Home/Compiler/lib/bootstrap.min.css
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										8
									
								
								Home/Compiler/lib/codemirror.min.css
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Home/Compiler/lib/codemirror.min.css
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										8
									
								
								Home/Compiler/lib/codemirror.min.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Home/Compiler/lib/codemirror.min.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										6
									
								
								Home/Compiler/lib/vue-2.6.0.min.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Home/Compiler/lib/vue-2.6.0.min.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										30
									
								
								Home/Compiler/main.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Home/Compiler/main.css
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
h1 {
 | 
			
		||||
  margin-top: 50px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pre {
 | 
			
		||||
  font-family: "Menlo", "Consolas", monospace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pre.error {
 | 
			
		||||
  color: red;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
hr {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.custom-file {
 | 
			
		||||
  width: 250px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.custom-file button {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  top: -38px;
 | 
			
		||||
  left: 255px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.editor {
 | 
			
		||||
  margin: 20px 0;
 | 
			
		||||
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								Home/Compiler/package.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Home/Compiler/package.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
{
 | 
			
		||||
  "name": "Compiler",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "main": "main.js",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "build": "webpack",
 | 
			
		||||
    "watch": "npm run build -- --watch"
 | 
			
		||||
  },
 | 
			
		||||
  "keywords": [],
 | 
			
		||||
  "author": "",
 | 
			
		||||
  "license": "ISC",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@babel/core": "^7.7.2",
 | 
			
		||||
    "@babel/preset-env": "^7.7.1",
 | 
			
		||||
    "babel-loader": "^8.0.6",
 | 
			
		||||
    "webpack": "^4.41.2",
 | 
			
		||||
    "webpack-cli": "^3.3.10"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								Home/Compiler/sandbox.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Home/Compiler/sandbox.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
<!DOCTYPE html>
 | 
			
		||||
<head>
 | 
			
		||||
  <title>sandbox</title>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
</body>
 | 
			
		||||
							
								
								
									
										571
									
								
								Home/Compiler/src/main.dev.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										571
									
								
								Home/Compiler/src/main.dev.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,571 @@
 | 
			
		|||
/* global Vue FileReader CodeMirror */
 | 
			
		||||
Vue.config.devtools = true
 | 
			
		||||
 | 
			
		||||
window.app = new Vue({
 | 
			
		||||
  el: '#root',
 | 
			
		||||
  data: {
 | 
			
		||||
    ast: {},
 | 
			
		||||
    editor: {},
 | 
			
		||||
    error: '',
 | 
			
		||||
    fileReader: new FileReader(),
 | 
			
		||||
    file: '',
 | 
			
		||||
    ids: [],
 | 
			
		||||
    js: '',
 | 
			
		||||
    json: '',
 | 
			
		||||
    lex: [],
 | 
			
		||||
    vars: [] // the value of ids
 | 
			
		||||
  },
 | 
			
		||||
  mounted () {
 | 
			
		||||
    this.editor = CodeMirror(document.querySelector('#editor'), {
 | 
			
		||||
      lineNumbers: true,
 | 
			
		||||
      tabSize: 2,
 | 
			
		||||
      extraKeys: {
 | 
			
		||||
        Tab: cm => {
 | 
			
		||||
          const spaces = Array(cm.getOption('indentUnit') + 1).join(' ')
 | 
			
		||||
          cm.replaceSelection(spaces)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    this.fileReader.onload = e => {
 | 
			
		||||
      this.editor.setValue(this.fileReader.result)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    fileHandler () {
 | 
			
		||||
      const file = document.querySelector('#file').files[0]
 | 
			
		||||
      if (file) this.file = file
 | 
			
		||||
      this.fileReader.readAsText(this.file)
 | 
			
		||||
    },
 | 
			
		||||
    reset () {
 | 
			
		||||
      this.error = ''
 | 
			
		||||
      this.ids = []
 | 
			
		||||
      this.vars = []
 | 
			
		||||
      this.lex = []
 | 
			
		||||
      this.json = ''
 | 
			
		||||
    },
 | 
			
		||||
    run () {
 | 
			
		||||
      try {
 | 
			
		||||
        this.reset()
 | 
			
		||||
        this.ast = parse(TokenStream(InputStream(this.editor.getValue())))
 | 
			
		||||
        this.js = '(function () { "use strict"; try { ' + makeJS(this.ast)
 | 
			
		||||
        this.ids = [...new Set(this.ids)]
 | 
			
		||||
        this.js +=
 | 
			
		||||
          ' parent.app.vars = [' +
 | 
			
		||||
          this.ids.join(', ') +
 | 
			
		||||
          ']; } catch (e) { parent.app.error = "Runtime Error: " + e.message; }}());'
 | 
			
		||||
        // recreate an iframe sandbox if it already exist
 | 
			
		||||
        // , then run the transpiled js in it
 | 
			
		||||
        const sb = document.querySelector('#sandbox')
 | 
			
		||||
        if (sb) sb.remove()
 | 
			
		||||
        const iframe = document.createElement('iframe')
 | 
			
		||||
        iframe.id = 'sandbox'
 | 
			
		||||
        iframe.style.display = 'none'
 | 
			
		||||
        iframe.src = 'sandbox.html'
 | 
			
		||||
        document.body.appendChild(iframe)
 | 
			
		||||
        const script = document.createElement('script')
 | 
			
		||||
        script.textContent = this.js
 | 
			
		||||
        document
 | 
			
		||||
          .querySelector('#sandbox')
 | 
			
		||||
          .contentDocument.body.appendChild(script)
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        this.error = e.message
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    lexer () {
 | 
			
		||||
      try {
 | 
			
		||||
        this.reset()
 | 
			
		||||
        const tokens = TokenStream(InputStream(this.editor.getValue()))
 | 
			
		||||
        while (!tokens.eof()) {
 | 
			
		||||
          this.lex.push(tokens.next())
 | 
			
		||||
        }
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        this.error = e.message
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    parser () {
 | 
			
		||||
      try {
 | 
			
		||||
        this.reset()
 | 
			
		||||
        this.ast = parse(TokenStream(InputStream(this.editor.getValue())))
 | 
			
		||||
        this.json = JSON.stringify(this.ast, null, 2)
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        this.error = e.message
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function InputStream (input) {
 | 
			
		||||
  let pos = 0
 | 
			
		||||
  let line = 1
 | 
			
		||||
  let col = 0
 | 
			
		||||
  return {
 | 
			
		||||
    next: next,
 | 
			
		||||
    peek: peek,
 | 
			
		||||
    eof: eof,
 | 
			
		||||
    croak: croak
 | 
			
		||||
  }
 | 
			
		||||
  function next () {
 | 
			
		||||
    const ch = input.charAt(pos++)
 | 
			
		||||
    if (ch === '\n') {
 | 
			
		||||
      line++
 | 
			
		||||
      col = 0
 | 
			
		||||
    } else col++
 | 
			
		||||
    return ch
 | 
			
		||||
  }
 | 
			
		||||
  function peek () {
 | 
			
		||||
    return input.charAt(pos)
 | 
			
		||||
  }
 | 
			
		||||
  function eof () {
 | 
			
		||||
    return peek() === ''
 | 
			
		||||
  }
 | 
			
		||||
  function croak (msg, type = 'Syntax') {
 | 
			
		||||
    throw new Error(type + ' Error: ' + msg + ' (' + line + ':' + col + ')')
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function TokenStream (input) {
 | 
			
		||||
  let current = null
 | 
			
		||||
  const reserved =
 | 
			
		||||
    ' abstract arguments boolean break byte case catch char class const continue' +
 | 
			
		||||
    ' debugger default delete do double else enum eval export extends false final' +
 | 
			
		||||
    ' finally float for function goto if implements import in instanceof int' +
 | 
			
		||||
    ' interface let long native new null package private protected public return' +
 | 
			
		||||
    ' short static super switch synchronized this throw throws transient true try' +
 | 
			
		||||
    ' typeof var void volatile while with yield '
 | 
			
		||||
  const keywords = ' begin for end if then else while int '
 | 
			
		||||
  const ops = ' + - * / = == != > < >= <= and or '
 | 
			
		||||
  return {
 | 
			
		||||
    next: next,
 | 
			
		||||
    peek: peek,
 | 
			
		||||
    eof: eof,
 | 
			
		||||
    croak: input.croak
 | 
			
		||||
  }
 | 
			
		||||
  function isKeyword (x) {
 | 
			
		||||
    return keywords.indexOf(' ' + x + ' ') >= 0
 | 
			
		||||
  }
 | 
			
		||||
  function isReservedWord (x) {
 | 
			
		||||
    return reserved.indexOf(' ' + x + ' ') >= 0
 | 
			
		||||
  }
 | 
			
		||||
  function isDigit (ch) {
 | 
			
		||||
    return /[0-9]/i.test(ch)
 | 
			
		||||
  }
 | 
			
		||||
  function isIdStart (ch) {
 | 
			
		||||
    return /[a-z_]/i.test(ch)
 | 
			
		||||
  }
 | 
			
		||||
  function isId (ch) {
 | 
			
		||||
    return isIdStart(ch) || '_0123456789'.indexOf(ch) >= 0
 | 
			
		||||
  }
 | 
			
		||||
  function isOpChar (ch, prev, prev2) {
 | 
			
		||||
    if (!prev) return '+-*/=!<>'.indexOf(ch) >= 0
 | 
			
		||||
    else if (
 | 
			
		||||
      (prev === '=' && !prev2) ||
 | 
			
		||||
      prev === '!' ||
 | 
			
		||||
      prev === '<' ||
 | 
			
		||||
      prev === '>'
 | 
			
		||||
    ) {
 | 
			
		||||
      return ch === '='
 | 
			
		||||
    }
 | 
			
		||||
    return false
 | 
			
		||||
  }
 | 
			
		||||
  function isOp (x) {
 | 
			
		||||
    return ops.indexOf(' ' + x + ' ') >= 0
 | 
			
		||||
  }
 | 
			
		||||
  function isPunc (ch) {
 | 
			
		||||
    return ',;()'.indexOf(ch) >= 0
 | 
			
		||||
  }
 | 
			
		||||
  function isWhitespace (ch) {
 | 
			
		||||
    return ' \t\n'.indexOf(ch) >= 0
 | 
			
		||||
  }
 | 
			
		||||
  function readWhile (predicate) {
 | 
			
		||||
    let str = ''
 | 
			
		||||
    while (
 | 
			
		||||
      !input.eof() &&
 | 
			
		||||
      predicate(input.peek(), str[str.length - 1], str[str.length - 2])
 | 
			
		||||
    ) {
 | 
			
		||||
      str += input.next()
 | 
			
		||||
    }
 | 
			
		||||
    return str
 | 
			
		||||
  }
 | 
			
		||||
  function readNumber () {
 | 
			
		||||
    const number = readWhile(isDigit)
 | 
			
		||||
    return { type: 'num', value: parseInt(number, 10) }
 | 
			
		||||
  }
 | 
			
		||||
  function readIdent () {
 | 
			
		||||
    const id = readWhile(isId)
 | 
			
		||||
    if (!isKeyword(id) && isReservedWord(id)) {
 | 
			
		||||
      input.croak('Variable name "' + id + '" is not allowed', 'Lexical')
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
      type: isKeyword(id) ? 'kw' : isOp(id) ? 'op' : 'var',
 | 
			
		||||
      value: id
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  function readOp () {
 | 
			
		||||
    const id = readWhile(isOpChar)
 | 
			
		||||
    return {
 | 
			
		||||
      type: isOp(id) ? 'op' : input.croak('Unknown symbol: ' + id, 'Lexical'),
 | 
			
		||||
      value: id
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  function skipComment () {
 | 
			
		||||
    readWhile(function (ch) {
 | 
			
		||||
      return ch !== '\n'
 | 
			
		||||
    })
 | 
			
		||||
    input.next()
 | 
			
		||||
  }
 | 
			
		||||
  function readNext () {
 | 
			
		||||
    readWhile(isWhitespace)
 | 
			
		||||
    if (input.eof()) return null
 | 
			
		||||
    const ch = input.peek()
 | 
			
		||||
    if (ch === '#') {
 | 
			
		||||
      skipComment()
 | 
			
		||||
      return readNext()
 | 
			
		||||
    }
 | 
			
		||||
    if (isDigit(ch)) return readNumber()
 | 
			
		||||
    if (isPunc(ch)) {
 | 
			
		||||
      return {
 | 
			
		||||
        type: 'punc',
 | 
			
		||||
        value: input.next()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (isOpChar(ch)) return readOp()
 | 
			
		||||
    if (isIdStart(ch)) return readIdent()
 | 
			
		||||
    input.croak('Invalid symbol: ' + ch, 'Lexical')
 | 
			
		||||
  }
 | 
			
		||||
  function peek () {
 | 
			
		||||
    return current || (current = readNext())
 | 
			
		||||
  }
 | 
			
		||||
  function next () {
 | 
			
		||||
    const tok = current
 | 
			
		||||
    current = null
 | 
			
		||||
    return tok || readNext()
 | 
			
		||||
  }
 | 
			
		||||
  function eof () {
 | 
			
		||||
    return peek() === null
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function parse (input) {
 | 
			
		||||
  const PRECEDENCE = {
 | 
			
		||||
    '=': 1,
 | 
			
		||||
    or: 2,
 | 
			
		||||
    and: 3,
 | 
			
		||||
    '<': 7,
 | 
			
		||||
    '>': 7,
 | 
			
		||||
    '<=': 7,
 | 
			
		||||
    '>=': 7,
 | 
			
		||||
    '==': 7,
 | 
			
		||||
    '!=': 7,
 | 
			
		||||
    '+': 10,
 | 
			
		||||
    '-': 10,
 | 
			
		||||
    '*': 20,
 | 
			
		||||
    '/': 20
 | 
			
		||||
  }
 | 
			
		||||
  return parseToplevel()
 | 
			
		||||
  function parseToplevel () {
 | 
			
		||||
    const prog = []
 | 
			
		||||
    while (!input.eof()) {
 | 
			
		||||
      prog.push(parseExpression())
 | 
			
		||||
      const last = prog.slice(-1)[0]
 | 
			
		||||
      if (requireSemicolon(last)) skipPunc(';')
 | 
			
		||||
    }
 | 
			
		||||
    return { type: 'prog', prog: prog }
 | 
			
		||||
  }
 | 
			
		||||
  function parseBlock () {
 | 
			
		||||
    const body = []
 | 
			
		||||
    while (!input.eof() && !isKw('else') && !isKw('end')) {
 | 
			
		||||
      body.push(parseExpression())
 | 
			
		||||
      const last = body.slice(-1)[0]
 | 
			
		||||
      if (requireSemicolon(last)) skipPunc(';')
 | 
			
		||||
    }
 | 
			
		||||
    return { type: 'block', body: body }
 | 
			
		||||
  }
 | 
			
		||||
  function parseExpression () {
 | 
			
		||||
    if (input.eof()) input.croak('Expecting an expression but reached EOF')
 | 
			
		||||
    return maybeBinary(parseAtom(), 0)
 | 
			
		||||
  }
 | 
			
		||||
  function parseAtom () {
 | 
			
		||||
    if (isPunc('(')) {
 | 
			
		||||
      input.next()
 | 
			
		||||
      const exp = parseExpression()
 | 
			
		||||
      skipPunc(')')
 | 
			
		||||
      return exp
 | 
			
		||||
    }
 | 
			
		||||
    if (isKw('begin')) return parseBegin()
 | 
			
		||||
    if (isKw('int')) return parseInit()
 | 
			
		||||
    if (isKw('for')) return parseFor()
 | 
			
		||||
    if (isKw('while')) return parseWhile()
 | 
			
		||||
    if (isKw('if')) return parseIf()
 | 
			
		||||
    if (isOp('-')) return parseUnary('-')
 | 
			
		||||
    if (isOp('+')) return parseUnary('+')
 | 
			
		||||
    const tok = input.next()
 | 
			
		||||
    if (tok.type === 'var' || tok.type === 'num') {
 | 
			
		||||
      return tok
 | 
			
		||||
    }
 | 
			
		||||
    input.croak('Unexpected token ' + tok.value)
 | 
			
		||||
  }
 | 
			
		||||
  function parseBegin () {
 | 
			
		||||
    skipKw('begin')
 | 
			
		||||
    const block = parseBlock()
 | 
			
		||||
    skipKw('end')
 | 
			
		||||
    return { type: 'begin', body: block.body }
 | 
			
		||||
  }
 | 
			
		||||
  function parseInit () {
 | 
			
		||||
    const vars = []
 | 
			
		||||
    let first = true
 | 
			
		||||
    skipKw('int')
 | 
			
		||||
    while (!input.eof()) {
 | 
			
		||||
      if (isPunc(';')) break
 | 
			
		||||
      if (first) first = false
 | 
			
		||||
      else skipPunc(',')
 | 
			
		||||
      if (isPunc(';')) break // the last "," can be missing
 | 
			
		||||
      const tok = parseExpression()
 | 
			
		||||
      if (tok.type !== 'var' && tok.type !== 'assign') {
 | 
			
		||||
        input.croak('Unexpected token ' + tok.type)
 | 
			
		||||
      }
 | 
			
		||||
      vars.push(tok)
 | 
			
		||||
    }
 | 
			
		||||
    skipPunc(';')
 | 
			
		||||
    return {
 | 
			
		||||
      type: 'init',
 | 
			
		||||
      vars: vars
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  function parseFor () {
 | 
			
		||||
    skipKw('for')
 | 
			
		||||
    skipPunc(',')
 | 
			
		||||
    const init = parseExpression()
 | 
			
		||||
    if (init.type !== 'assign') {
 | 
			
		||||
      input.croak('Unexpected token ' + init.type)
 | 
			
		||||
    }
 | 
			
		||||
    skipPunc(',')
 | 
			
		||||
    const cond = parseExpression()
 | 
			
		||||
    isRval(cond)
 | 
			
		||||
    skipPunc(',')
 | 
			
		||||
    const inc = parseExpression()
 | 
			
		||||
    isRval(inc)
 | 
			
		||||
    skipPunc(';')
 | 
			
		||||
    const body = parseBlock()
 | 
			
		||||
    skipKw('end')
 | 
			
		||||
    return {
 | 
			
		||||
      type: 'for',
 | 
			
		||||
      init: init,
 | 
			
		||||
      cond: cond,
 | 
			
		||||
      inc: inc,
 | 
			
		||||
      body: body
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  function parseWhile () {
 | 
			
		||||
    skipKw('while')
 | 
			
		||||
    skipPunc('(')
 | 
			
		||||
    const cond = parseExpression()
 | 
			
		||||
    isRval(cond)
 | 
			
		||||
    skipPunc(')')
 | 
			
		||||
    const body = parseBlock()
 | 
			
		||||
    skipKw('end')
 | 
			
		||||
    return { type: 'while', cond: cond, body: body }
 | 
			
		||||
  }
 | 
			
		||||
  function parseIf () {
 | 
			
		||||
    skipKw('if')
 | 
			
		||||
    skipPunc('(')
 | 
			
		||||
    const cond = parseExpression()
 | 
			
		||||
    isRval(cond)
 | 
			
		||||
    skipPunc(')')
 | 
			
		||||
    skipKw('then')
 | 
			
		||||
    const then = parseBlock()
 | 
			
		||||
    const ret = { type: 'if', cond: cond, then: then }
 | 
			
		||||
    if (isKw('else')) {
 | 
			
		||||
      input.next()
 | 
			
		||||
      ret.else = parseBlock()
 | 
			
		||||
    }
 | 
			
		||||
    skipKw('end')
 | 
			
		||||
    return ret
 | 
			
		||||
  }
 | 
			
		||||
  function parseUnary (op) {
 | 
			
		||||
    skipOp(op)
 | 
			
		||||
    const right = parseAtom()
 | 
			
		||||
    isRval(right)
 | 
			
		||||
    return { type: 'unary', operator: op, right: right }
 | 
			
		||||
  }
 | 
			
		||||
  function maybeBinary (left, myPrec) {
 | 
			
		||||
    if (left.type === 'assign' && left.left.type !== 'var') {
 | 
			
		||||
      input.croak('Invalid left-hand side in assignment')
 | 
			
		||||
    }
 | 
			
		||||
    const tok = isOp()
 | 
			
		||||
    if (tok) {
 | 
			
		||||
      const hisPrec = PRECEDENCE[tok.value]
 | 
			
		||||
      if (hisPrec > myPrec) {
 | 
			
		||||
        input.next()
 | 
			
		||||
        const right = maybeBinary(parseAtom(), hisPrec)
 | 
			
		||||
        isRval(left)
 | 
			
		||||
        isRval(right)
 | 
			
		||||
        return maybeBinary(
 | 
			
		||||
          {
 | 
			
		||||
            type: tok.value === '=' ? 'assign' : 'binary',
 | 
			
		||||
            operator: tok.value,
 | 
			
		||||
            left: left,
 | 
			
		||||
            right: right
 | 
			
		||||
          },
 | 
			
		||||
          myPrec
 | 
			
		||||
        )
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return left
 | 
			
		||||
  }
 | 
			
		||||
  function isPunc (ch) {
 | 
			
		||||
    var tok = input.peek()
 | 
			
		||||
    return tok && tok.type === 'punc' && (!ch || tok.value === ch) && tok
 | 
			
		||||
  }
 | 
			
		||||
  function isKw (kw) {
 | 
			
		||||
    var tok = input.peek()
 | 
			
		||||
    return tok && tok.type === 'kw' && (!kw || tok.value === kw) && tok
 | 
			
		||||
  }
 | 
			
		||||
  function isOp (op) {
 | 
			
		||||
    var tok = input.peek()
 | 
			
		||||
    return tok && tok.type === 'op' && (!op || tok.value === op) && tok
 | 
			
		||||
  }
 | 
			
		||||
  function isRval (tok) {
 | 
			
		||||
    if (
 | 
			
		||||
      tok.type !== 'var' &&
 | 
			
		||||
      tok.type !== 'num' &&
 | 
			
		||||
      tok.type !== 'unary' &&
 | 
			
		||||
      tok.type !== 'binary'
 | 
			
		||||
    ) {
 | 
			
		||||
      input.croak('Unexpected token ' + tok.type)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  function skipOp (ch) {
 | 
			
		||||
    if (isOp(ch)) input.next()
 | 
			
		||||
    else if (!input.eof()) {
 | 
			
		||||
      input.croak('Expecting ' + ch + ' but got ' + input.peek().value)
 | 
			
		||||
    } else {
 | 
			
		||||
      input.croak('Expecting ' + ch + ' but reached EOF')
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  function skipPunc (ch) {
 | 
			
		||||
    if (isPunc(ch)) input.next()
 | 
			
		||||
    else if (!input.eof()) {
 | 
			
		||||
      input.croak('Expecting ' + ch + ' but got ' + input.peek().value)
 | 
			
		||||
    } else {
 | 
			
		||||
      input.croak('Expecting ' + ch + ' but reached EOF')
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  function skipKw (kw) {
 | 
			
		||||
    if (isKw(kw)) input.next()
 | 
			
		||||
    else if (!input.eof()) {
 | 
			
		||||
      input.croak('Expecting ' + kw + ' but got ' + input.peek().value)
 | 
			
		||||
    } else {
 | 
			
		||||
      input.croak('Expecting ' + kw + ' but reached EOF')
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  function isBlock (tok) {
 | 
			
		||||
    return (
 | 
			
		||||
      tok.type === 'begin' ||
 | 
			
		||||
      tok.type === 'for' ||
 | 
			
		||||
      tok.type === 'while' ||
 | 
			
		||||
      tok.type === 'if'
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
  function requireSemicolon (tok) {
 | 
			
		||||
    return !isBlock(tok) && tok.type !== 'init'
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function makeJS (ast) {
 | 
			
		||||
  return js(ast)
 | 
			
		||||
  function js (ast) {
 | 
			
		||||
    const cases = [
 | 
			
		||||
      'js_num',
 | 
			
		||||
      'js_var',
 | 
			
		||||
      'js_unary',
 | 
			
		||||
      'js_binary',
 | 
			
		||||
      'js_assign',
 | 
			
		||||
      'js_init',
 | 
			
		||||
      'js_begin',
 | 
			
		||||
      'js_block',
 | 
			
		||||
      'js_prog',
 | 
			
		||||
      'js_for',
 | 
			
		||||
      'js_while',
 | 
			
		||||
      'js_if'
 | 
			
		||||
    ]
 | 
			
		||||
    const handler = {
 | 
			
		||||
      js_num (ast) {
 | 
			
		||||
        return JSON.stringify(ast.value)
 | 
			
		||||
      },
 | 
			
		||||
      js_var (ast) {
 | 
			
		||||
        window.app.ids.push(ast.value)
 | 
			
		||||
        return ast.value
 | 
			
		||||
      },
 | 
			
		||||
      js_unary (ast) {
 | 
			
		||||
        const op = ast.operator
 | 
			
		||||
        return '( ' + op + js(ast.right) + ' )'
 | 
			
		||||
      },
 | 
			
		||||
      js_binary (ast) {
 | 
			
		||||
        let op = ' ' + ast.operator + ' '
 | 
			
		||||
        if (op === ' and ') op = ' && '
 | 
			
		||||
        if (op === ' or ') op = ' || '
 | 
			
		||||
        if (op === ' / ') {
 | 
			
		||||
          return 'Math.trunc(' + js(ast.left) + op + js(ast.right) + ')'
 | 
			
		||||
        }
 | 
			
		||||
        return '( ' + js(ast.left) + op + js(ast.right) + ' )'
 | 
			
		||||
      },
 | 
			
		||||
      js_assign (ast) {
 | 
			
		||||
        return js(ast.left) + ' = ' + js(ast.right)
 | 
			
		||||
      },
 | 
			
		||||
      js_init (ast) {
 | 
			
		||||
        const vars = []
 | 
			
		||||
        for (let i = 0; i < ast.vars.length; i += 1) {
 | 
			
		||||
          vars.push(js(ast.vars[i]))
 | 
			
		||||
        }
 | 
			
		||||
        return 'var ' + vars.join(', ')
 | 
			
		||||
      },
 | 
			
		||||
      js_prog (ast) {
 | 
			
		||||
        const prog = []
 | 
			
		||||
        for (let i = 0; i < ast.prog.length; i += 1) {
 | 
			
		||||
          prog.push(js(ast.prog[i]))
 | 
			
		||||
        }
 | 
			
		||||
        return prog.join('; ') + ';'
 | 
			
		||||
      },
 | 
			
		||||
      js_block (ast) {
 | 
			
		||||
        const body = []
 | 
			
		||||
        for (let i = 0; i < ast.body.length; i += 1) {
 | 
			
		||||
          body.push(js(ast.body[i]))
 | 
			
		||||
        }
 | 
			
		||||
        return body.join('; ') + ';'
 | 
			
		||||
      },
 | 
			
		||||
      js_begin (ast) {
 | 
			
		||||
        return this.js_block(ast)
 | 
			
		||||
      },
 | 
			
		||||
      js_for (ast) {
 | 
			
		||||
        return (
 | 
			
		||||
          'for (' +
 | 
			
		||||
          js(ast.init) +
 | 
			
		||||
          '; ' +
 | 
			
		||||
          js(ast.cond) +
 | 
			
		||||
          '; ' +
 | 
			
		||||
          js(ast.init.left) +
 | 
			
		||||
          ' += ' +
 | 
			
		||||
          js(ast.inc) +
 | 
			
		||||
          ') { ' +
 | 
			
		||||
          js(ast.body) +
 | 
			
		||||
          ' }'
 | 
			
		||||
        )
 | 
			
		||||
      },
 | 
			
		||||
      js_while (ast) {
 | 
			
		||||
        return 'while (' + js(ast.cond) + ') { ' + js(ast.body) + ' }'
 | 
			
		||||
      },
 | 
			
		||||
      js_if (ast) {
 | 
			
		||||
        let str = 'if (' + js(ast.cond) + ') { ' + js(ast.then) + ' }'
 | 
			
		||||
        if (ast.else) {
 | 
			
		||||
          str += ' else { ' + js(ast.else) + ' }'
 | 
			
		||||
        }
 | 
			
		||||
        return str
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    for (let i = 0; i < cases.length; i += 1) {
 | 
			
		||||
      if ('js_' + ast.type === cases[i]) {
 | 
			
		||||
        return handler[cases[i]](ast)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								Home/Compiler/test.big5.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Home/Compiler/test.big5.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
begin
 | 
			
		||||
  int x=0, zzz = 5;
 | 
			
		||||
  int i, j = 1;
 | 
			
		||||
 | 
			
		||||
  # 進行迴圈計算
 | 
			
		||||
  for, i=1, i<=50, j; # j是i每次增加的數值
 | 
			
		||||
    x=x+1;
 | 
			
		||||
  end # for
 | 
			
		||||
 | 
			
		||||
  if ((x>5) and (j<=8)) then
 | 
			
		||||
    x=1;
 | 
			
		||||
  else
 | 
			
		||||
    for, i=1, i<=50, j+1;
 | 
			
		||||
      x=x+1;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    while (i < 11)
 | 
			
		||||
      yy = x;
 | 
			
		||||
      i = i + 1;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  end # if
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										24
									
								
								Home/Compiler/test.utf8.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Home/Compiler/test.utf8.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
begin
 | 
			
		||||
  int x=0, zzz = 5;
 | 
			
		||||
  int i, j = 1;
 | 
			
		||||
 | 
			
		||||
  # 進行迴圈計算
 | 
			
		||||
  for, i=1, i<=50, j; # j是i每次增加的數值
 | 
			
		||||
    x=x+1;
 | 
			
		||||
  end # for
 | 
			
		||||
 | 
			
		||||
  if ((x>5) and (j<=8)) then
 | 
			
		||||
    x=1;
 | 
			
		||||
  else
 | 
			
		||||
    for, i=1, i<=50, j+1;
 | 
			
		||||
      x=x+1;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    while (i < 11)
 | 
			
		||||
      yy = x;
 | 
			
		||||
      i = i + 1;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  end # if
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										13
									
								
								Home/Compiler/webpack.config.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Home/Compiler/webpack.config.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
const path = require('path')
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  mode: 'none',
 | 
			
		||||
  entry: './src/main.dev.js',
 | 
			
		||||
  output: {
 | 
			
		||||
    path: path.resolve(__dirname, './'),
 | 
			
		||||
    filename: 'main.js'
 | 
			
		||||
  },
 | 
			
		||||
  module: {
 | 
			
		||||
    rules: [{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue