Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program compiler;
- uses crt, memory;
- type
- pNodeList = ^tNodeList;
- tNodeList = record
- value: String[30];
- token: String[20];
- base: String[20];
- lineCount : integer;
- idx : integer;
- next: pNodeList;
- end;
- LinkedList = record
- first: pNodeList;
- last: pNodeList;
- size: Integer;
- end;
- var
- list:LinkedList;
- it:Integer;
- itLL:pNodeList;
- node:pNodeList;
- main: String;
- Outfile : Text;
- error_count : integer;
- globalVar:LinkedList;
- localVar:LinkedList;
- funcList:LinkedList;
- fileList:LinkedList;
- recordList:LinkedList;
- recordVarList:LinkedList;
- valName : string;
- valType : string;
- count : integer;
- jsfile : Text;
- varBase : string;
- Userfile : Text;
- line : String;
- str : String;
- token : String;
- readlnCount : integer;
- c:char;
- noFuncFlag : integer;
- gl : string;
- procedure newLL(var list: LinkedList); forward;
- procedure addToLL(var list: LinkedList; inVal:string;token: String); forward;
- procedure addToLL2(var list: LinkedList; inVal:string;token: String; base: String); forward;
- procedure addToLL3(lineCount: integer; idx: integer; var list: LinkedList; inVal:string; token: String); forward;
- procedure nextLL(var tNode: pNodeList); forward;
- procedure getLL(var list: LinkedList; var tNode: pNodeList; name : string); forward;
- procedure readfile(var list: LinkedList); forward;
- procedure start; forward;
- procedure js(s: string); forward;
- procedure jsln(s: string); forward;
- procedure error; forward;
- procedure errorPr; forward;
- procedure next; forward;
- function cur: string; forward;
- function val: string; forward;
- procedure semicolon_; forward;
- function value(par: string) : string; forward;
- procedure type_; forward;
- procedure var_; forward;
- function factor_(z: integer):string; forward;
- function term_(z: integer):string; forward;
- function expr_(z: integer):string; forward;
- function bfactor_(z: integer):string; forward;
- function bterm_(z: integer):string; forward;
- function bexpr_(z: integer):string; forward;
- procedure writeln_; forward;
- procedure write_; forward;
- procedure function_; forward;
- procedure procedure_; forward;
- procedure initLocVar; forward;
- procedure for_; forward;
- procedure while_; forward;
- procedure repeat_; forward;
- procedure header_; forward;
- procedure assign_; forward;
- procedure line_; forward;
- function index_:string; forward;
- procedure else_(z: integer); forward;
- procedure if_(z: integer); forward;
- function function_arg_:string; forward;
- procedure main_; forward;
- procedure program_; forward;
- procedure lowcase(var str : string); forward;
- procedure openfile; forward;
- procedure closefile; forward;
- procedure assignfile_; forward;
- procedure resetfile_; forward;
- procedure closefile_; forward;
- procedure rewritefile_; forward;
- procedure newLL(var list: LinkedList);
- begin
- list.size:=0;
- list.first := nil;
- list.last := nil;
- end;
- procedure addToLL(var list: LinkedList; inVal:string; token: String);
- var newNode:pNodeList;
- begin
- if (list.size = 0) then begin
- {new(list.first);}
- list.first := memalloc (SizeOf(tNodeList));
- list.first^.value:=inVal;
- list.first^.token:=token;
- list.first^.base:='';
- list.first^.next := nil;
- list.last:=list.first;
- end else begin
- {new(newNode);}
- newNode := memalloc (SizeOf(tNodeList));
- newNode^.value := inVal;
- newNode^.token := token;
- newNode^.next := nil;
- newNode^.base:='';
- list.last^.next := newNode;
- list.last := newNode;
- end;
- list.size := list.size + 1;
- end;
- procedure addToLL3(lineCount: integer; idx: integer; var list: LinkedList; inVal:string; token: String);
- var newNode:pNodeList;
- begin
- if (list.size = 0) then begin
- {new(list.first);}
- list.first := memalloc (SizeOf(tNodeList));
- list.first^.value:=inVal;
- list.first^.token:=token;
- list.first^.base:='';
- list.first^.lineCount:=lineCount;
- list.first^.idx:=idx;
- list.first^.next := nil;
- list.last:=list.first;
- end else begin
- {new(newNode);}
- newNode := memalloc (SizeOf(tNodeList));
- newNode^.value := inVal;
- newNode^.token := token;
- newNode^.next := nil;
- newNode^.base:='';
- newNode^.lineCount:=lineCount;
- newNode^.idx:=idx;
- list.last^.next := newNode;
- list.last := newNode;
- end;
- list.size := list.size + 1;
- end;
- procedure addToLL2(var list: LinkedList; inVal:string;token: String; base: String);
- var newNode:pNodeList;
- begin
- if list.size = 0 then begin
- {new(list.first);}
- list.first := memalloc (SizeOf(tNodeList));
- list.first^.value:=inVal;
- list.first^.token:=token;
- list.first^.base:=base;
- list.first^.next := nil;
- list.last:=list.first;
- end else begin
- {new(newNode);}
- newNode := memalloc (SizeOf(tNodeList));
- newNode^.value := inVal;
- newNode^.token := token;
- newNode^.base:=base;
- newNode^.next := nil;
- list.last^.next := newNode;
- list.last := list.last^.next;
- end;
- list.size := list.size + 1;
- end;
- procedure nextLL(var tNode: pNodeList);
- begin
- if tNode <> nil then begin
- tNode:=tNode^.next;
- end else begin
- writeln(outfile, '$e next from null!!!');
- end;
- end;
- procedure getLL(var list: LinkedList; var tNode: pNodeList; name : string);
- var node2:pNodeList;
- begin
- tNode := nil;
- if list.size = 0 then begin
- tNode := nil;
- end else begin
- node2 := list.first;
- while (node2 <> nil) do begin
- if (node2^.value = name) then begin
- {tNode := node2;}
- tNode := memalloc (SizeOf(tNodeList));
- tNode^.value := node2^.value;
- tNode^.token := node2^.token;
- tNode^.base:=node2^.base;
- tNode^.next := nil;
- end;
- node2:=node2^.next;
- end;
- end;
- end;
- procedure lowcase(var str : string);
- var i : Integer;
- begin
- for i:=1 to length(str) do begin
- if (ord(str[i]) >= ord('A')) and (ord(str[i]) <= ord('Z')) then begin
- str[i] := chr(ord(str[i]) - ord('A') + ord('a'));
- end;
- end;
- end;
- procedure readfile(var list: LinkedList);
- var lineCount : integer;
- idxCount : integer;
- begin
- Assign(Userfile, 'in.pas');
- Reset(Userfile);
- lineCount := 0;
- idxCount := 0;
- Repeat
- Readln(Userfile,line);
- lineCount := lineCount + 1;
- lowcase(line);
- {addToLL(list, line, '---------------------');}
- str:='';
- token:='';
- it := 1;
- while it <= length(line) do begin
- c := line[it];
- if c = '{' then begin
- addToLL3(lineCount, idxCount, list, c, 'brace_{');
- idxCount := idxCount + 1;
- end else if c = '}' then begin
- addToLL3(lineCount, idxCount, list, c, 'brace_}');
- idxCount := idxCount + 1;
- end else if c = '(' then begin
- addToLL3(lineCount, idxCount, list, c, 'brace_(');
- idxCount := idxCount + 1;
- end else if c = ')' then begin
- addToLL3(lineCount, idxCount, list, c, 'brace_)');
- idxCount := idxCount + 1;
- end else if c = '[' then begin
- addToLL3(lineCount, idxCount, list, c, 'brace_[');
- idxCount := idxCount + 1;
- end else if c = ']' then begin
- addToLL3(lineCount, idxCount, list, c, 'brace_]');
- idxCount := idxCount + 1;
- end else if c = '+' then begin
- addToLL3(lineCount, idxCount, list, c, 'plus');
- idxCount := idxCount + 1;
- end else if c = '-' then begin
- addToLL3(lineCount, idxCount, list, c, 'minus');
- idxCount := idxCount + 1;
- end else if c = '*' then begin
- addToLL3(lineCount, idxCount, list, c, 'mul');
- idxCount := idxCount + 1;
- end else if c = '/' then begin
- addToLL3(lineCount, idxCount, list, c, 'divide');
- end else if c = ';' then begin
- addToLL3(lineCount, idxCount, list, c, 'semicolon');
- idxCount := idxCount + 1;
- end else if c = ',' then begin
- addToLL3(lineCount, idxCount, list, c, 'comma');
- idxCount := idxCount + 1;
- end else if c = '.' then begin
- addToLL3(lineCount, idxCount, list, c, 'dot');
- idxCount := idxCount + 1;
- end else if c = '^' then begin
- addToLL3(lineCount, idxCount, list, c, 'pointer');
- idxCount := idxCount + 1;
- end else if c = '=' then begin
- addToLL3(lineCount, idxCount, list, c, '=');
- idxCount := idxCount + 1;
- end else if c = '<' then begin
- if line[it+1]='>' then begin
- addToLL3(lineCount, idxCount, list, '<>', '<>');
- idxCount := idxCount + 1;
- it := it + 1;
- end else if line[it+1]='=' then begin
- addToLL3(lineCount, idxCount, list, '<=', '<=');
- idxCount := idxCount + 1;
- it := it + 1;
- end else begin
- addToLL3(lineCount, idxCount, list, c, '<');
- idxCount := idxCount + 1;
- end;
- end else if c = '>' then begin
- if line[it+1]='=' then begin
- addToLL3(lineCount, idxCount, list, '>=', '>=');
- idxCount := idxCount + 1;
- it := it + 1;
- end else begin
- addToLL3(lineCount, idxCount, list, c, '>');
- idxCount := idxCount + 1;
- end;
- end else if c = chr(39) then begin
- it := it + 1;
- while (it <= length(line)) and (line[it] <> chr(39)) do begin
- if line[it] = chr(34) then begin
- str := str + chr(92);
- end;
- if line[it] = chr(92) then begin
- str := str + chr(92);
- end;
- str := str + line[it];
- it := it + 1;
- end;
- addToLL3(lineCount, idxCount, list, str, 'str');
- idxCount := idxCount + 1;
- str := '';
- end else if c = ':' then begin
- if line[it+1]='=' then begin
- addToLL3(lineCount, idxCount, list, ':=', 'assign');
- idxCount := idxCount + 1;
- it := it + 1;
- end else begin
- addToLL3(lineCount, idxCount, list, c, 'colon');
- idxCount := idxCount + 1;
- end;
- end else if (ord(c) >= ord('0')) and (ord(c) <= ord('9')) then begin
- while (it <= length(line)) and (ord(line[it]) >= ord('0')) and (ord(line[it]) <= ord('9')) do begin
- str := str + line[it];
- it := it + 1;
- end;
- addToLL3(lineCount, idxCount, list, str, 'number');
- idxCount := idxCount + 1;
- str := '';
- Continue;
- end else if ((ord(c) >= ord('a')) and (ord(c) <= ord('z'))) or (c = '_') then begin
- token := 'var';
- while (it <= length(line)) and (((ord(line[it]) >= ord('0')) and (ord(line[it]) <= ord('9')))
- or ((ord(line[it]) >= ord('a')) and (ord(line[it]) <= ord('z'))) or (line[it] = '_')) do begin
- str := str + line[it];
- it := it + 1;
- end;
- if str = 'begin' then begin
- addToLL3(lineCount, idxCount, list, str, 'begin');
- idxCount := idxCount + 1;
- end else if str = 'end' then begin
- addToLL3(lineCount, idxCount, list, str, 'end');
- end else if str = 'if' then begin
- addToLL3(lineCount, idxCount, list, str, 'if');
- end else if str = 'and' then begin
- addToLL3(lineCount, idxCount, list, str, 'and');
- end else if str = 'or' then begin
- addToLL3(lineCount, idxCount, list, str, 'or');
- end else if str = 'for' then begin
- addToLL3(lineCount, idxCount, list, str, 'for');
- end else if str = 'to' then begin
- addToLL3(lineCount, idxCount, list, str, 'to');
- end else if str = 'do' then begin
- addToLL3(lineCount, idxCount, list, str, 'do');
- end else if str = 'while' then begin
- addToLL3(lineCount, idxCount, list, str, 'while');
- end else if str = 'repeat' then begin
- addToLL3(lineCount, idxCount, list, str, 'repeat');
- end else if str = 'until' then begin
- addToLL3(lineCount, idxCount, list, str, 'until');
- end else if str = 'unit' then begin
- addToLL3(lineCount, idxCount, list, str, 'unit');
- end else if str = 'program' then begin
- addToLL3(lineCount, idxCount, list, str, 'program');
- end else if str = 'uses' then begin
- addToLL3(lineCount, idxCount, list, str, 'uses');
- end else if str = 'type' then begin
- addToLL3(lineCount, idxCount, list, str, 'type');
- end else if str = 'string' then begin
- addToLL3(lineCount, idxCount, list, str, 'string');
- end else if str = 'integer' then begin
- addToLL3(lineCount, idxCount, list, str, 'integer');
- end else if str = 'char' then begin
- addToLL3(lineCount, idxCount, list, str, 'char');
- end else if str = 'procedure' then begin
- addToLL3(lineCount, idxCount, list, str, 'procedure');
- end else if str = 'function' then begin
- addToLL3(lineCount, idxCount, list, str, 'function');
- end else if str = 'writeln' then begin
- addToLL3(lineCount, idxCount, list, str, 'writeln');
- end else if str = 'write' then begin
- addToLL3(lineCount, idxCount, list, str, 'write');
- end else if str = 'readln' then begin
- addToLL3(lineCount, idxCount, list, str, 'readln');
- end else if str = 'record' then begin
- addToLL3(lineCount, idxCount, list, str, 'record');
- end else if str = 'interface' then begin
- addToLL3(lineCount, idxCount, list, str, 'interface');
- end else if str = 'implementation' then begin
- addToLL3(lineCount, idxCount, list, str, 'implementation');
- end else if str = 'var' then begin
- addToLL3(lineCount, idxCount, list, str, 'var');
- end else if str = 'then' then begin
- addToLL3(lineCount, idxCount, list, str, 'then');
- end else if str = 'else' then begin
- addToLL3(lineCount, idxCount, list, str, 'else');
- end else if str = 'case' then begin
- addToLL3(lineCount, idxCount, list, str, 'case');
- end else if str = 'assign' then begin
- addToLL3(lineCount, idxCount, list, str, 'assign');
- end else if str = 'reset' then begin
- addToLL3(lineCount, idxCount, list, str, 'reset');
- end else if str = 'rewrite' then begin
- addToLL3(lineCount, idxCount, list, str, 'rewrite');
- end else if str = 'text' then begin
- addToLL3(lineCount, idxCount, list, str, 'text');
- end else if str = 'clrscr' then begin
- addToLL3(lineCount, idxCount, list, str, 'clrscr');
- end else if str = 'continue' then begin
- addToLL3(lineCount, idxCount, list, str, 'continue');
- end else if str = 'close' then begin
- addToLL3(lineCount, idxCount, list, str, 'close');
- end else if str = 'forward' then begin
- addToLL3(lineCount, idxCount, list, str, 'forward');
- end else begin
- addToLL3(lineCount, idxCount, list, str, 'variable');
- end;
- idxCount := idxCount + 1;
- str := '';
- Continue;
- end;
- it := it + 1;
- end;
- Until Eof(Userfile);
- Close(Userfile);
- end;
- procedure js(s: string);
- begin
- write(jsfile, s);
- end;
- procedure jsln(s: string);
- begin
- writeln(jsfile, s);
- end;
- procedure error;
- begin
- error_count := error_count + 1;
- if node <> nil then begin
- writeln(Outfile, '$e ',val,' {line: ',node^.lineCount,' idx: ',node^.idx,'}');
- end else begin
- writeln(outfile, '$e error null');
- end;
- nextLL(node);
- end;
- procedure errorPr;
- begin
- error_count := error_count + 1;
- if node <> nil then begin
- writeln(Outfile, '$e ',val,' {line: ',node^.lineCount,' idx: ',node^.idx,'}');
- end else begin
- writeln(outfile, '$e error null');
- end;
- end;
- procedure next;
- begin
- writeln(Outfile, '> ', val);
- nextLL(node);
- end;
- function cur: string;
- begin
- if node <> nil then begin
- cur := node^.token;
- end else begin
- cur := '$cur';
- end;
- end;
- function val: string;
- begin
- if node <> nil then begin
- val := node^.value;
- end else begin
- val := '$val';
- end;
- end;
- procedure semicolon_;
- begin
- if cur = 'semicolon' then begin
- next;
- end else begin
- write(outfile, 'error semicolon ');
- errorPr;
- end;
- end;
- function index_ : string;
- var res : string;
- begin
- res := '';
- if (node^.next <> nil) and (node^.next^.token = 'brace_[') then begin
- next;
- next;
- res := '[(' + expr_(0) + ') - 1]';
- end;
- index_ := res;
- end;
- function value(par: string) : string;
- var
- tNode : pNodeList;
- res : string;
- after : string;
- begin
- after := '.val';
- if par <> 'assign' then begin
- tNode := nil;
- getLL(funcList, tNode, val);
- if tNode <> nil then begin
- after := '.f';
- varBase := gl + '.funcs.';
- end;
- end;
- if cur = 'str' then begin
- res := ('"' + val + '"');
- end else if cur = 'number' then begin
- res := val;
- end else if cur = 'variable' then begin
- if val = 'memalloc' then begin
- res := '{}';
- while (node^.next <> nil) and (node^.next^.token <> 'semicolon') do begin
- next;
- end;
- end else if val = 'ord' then begin
- next;
- next;
- res := '((';
- res := res + expr_(0);
- res := res + ').charCodeAt(0))';
- end else if val = 'length' then begin
- next;
- next;
- res := '(';
- res := res + expr_(0);
- res := res + ').length';
- end else if val = 'chr' then begin
- next;
- next;
- res := 'String.fromCharCode(';
- res := res + expr_(0);
- res := res + ')';
- end else if (val = 'line') and (node^.next^.token = 'brace_(') then begin
- next;
- next;
- res := 'line(';
- res := res + expr_(0) + ',';
- next;
- res := res + expr_(0) + ',';
- next;
- res := res + expr_(0) + ',';
- next;
- res := res + expr_(0);
- next;
- res := res + ');';
- end else if val = 'eof' then begin
- next;
- next;
- res := 'eof(';
- res := res + gl + '.' + val;
- res := res + ')';
- next;
- end else if val = 'nil' then begin
- res := 'null';
- end else begin
- tNode := nil;
- getLL(localVar, tNode, val);
- if ((localVar.size = 0) or (tNode = nil)) and (after <> '.f') then begin
- varBase := gl + '.';
- end;
- if (tNode <> nil) and (after <> '.f') then begin
- varBase := tNode^.base;
- after := '.val';
- noFuncFlag := 1;
- end;
- res := (varBase + val + after);
- end;
- end else begin
- res := '';
- end;
- res := res + index_;
- while (node^.next^.token = 'dot') or (node^.next^.token = 'pointer') do begin
- noFuncFlag := 1;
- res := res + index_;
- if node^.next^.token = 'pointer' then begin
- next;
- end;
- res := res + '.';
- next;
- next;
- res := res + val;
- end;
- value := res;
- end;
- procedure type_;
- var tmp : integer;
- valName : string;
- begin
- tmp := 0;
- while cur = 'variable' do begin
- tmp := tmp + 1;
- js(val);
- valName := val;
- next;
- if cur = '=' then begin
- jsln(': { f : function(obj) { ');
- next;
- if cur = 'pointer' then begin
- addToLL(recordList, valName, 'pas.' + main + '.');
- next;
- jsln('var tmp = {};');
- jsln('tmp.val = null;');
- jsln('return tmp;');
- jsln('}},');
- next;
- next;
- continue;
- end;
- if cur = 'record' then begin
- next;
- end else begin
- error;
- end;
- addToLL(recordList, valName, 'pas.' + main + '.');
- jsln('obj.val = {};');
- while cur = 'variable' do begin
- {jsln('obj.val.' + val + '= тут пустой объект ;');}
- js('obj.val.' + val + '=');
- valName := val;
- next;
- if cur = 'colon' then begin
- next;
- valType := val;
- if cur = 'integer' then begin
- jsln('0;');
- next;
- semicolon_;
- end else if (cur = 'string') or (cur = 'char') then begin
- jsln('"";');
- next;
- semicolon_;
- end else begin
- jsln('null;');
- next;
- semicolon_;
- writeln(outfile, 'error type_ undif type');
- end;
- end else begin
- write(outfile, 'error type_ no colon');
- error;
- end;
- end;
- end else begin
- write(outfile, 'error type_ no colon');
- error;
- end;
- jsln('return obj;}');
- jsln('},');
- if cur = 'end' then begin
- next;
- semicolon_;
- end else begin
- write(outfile, 'error type_ no end of record');
- error;
- end;
- end;
- if tmp = 0 then begin
- write(outfile, 'error type_ no variable');
- error;
- end;
- end;
- procedure var_;
- var
- tmp : integer;
- valName : string;
- valType : string;
- tNode : pNodeList;
- begin
- tmp := 0;
- while cur = 'variable' do begin
- tmp := tmp + 1;
- js(val);
- valName := val;
- next;
- if cur = 'colon' then begin
- js(':');
- next;
- valType := val;
- addToLL2(globalVar, valName, valType, 'pas.' + main + '.');
- if cur = 'integer' then begin
- js('{val:0}');
- jsln(',');
- next;
- semicolon_;
- end else if (cur = 'string') or (cur = 'char') then begin
- js('{val:""}');
- jsln(',');
- next;
- semicolon_;
- end else if (cur = 'text') then begin
- js('{val:{}}');
- addToLL(fileList, valName, 'text');
- jsln(',');
- next;
- semicolon_;
- end else if cur = 'variable' then begin
- tNode := nil;
- getLL(recordList, tNode, val);
- if tNode <> nil then begin
- addToLL(recordVarList, valName, val);
- js('{val:{}}');
- next;
- semicolon_;
- jsln(',');
- end else begin
- write(outfile, 'error var_ variable type undif');
- error;
- end;
- end else begin
- write(outfile, 'error var_ undif type');
- error;
- end;
- end else begin
- write(outfile, 'error var_ no colon');
- error;
- end;
- end;
- if tmp = 0 then begin
- write(outfile, 'error var_ no variable');
- error;
- end;
- end;
- function factor_ (z: integer): string;
- var tNode : pNodeList;
- res : string;
- begin
- res := '';
- noFuncFlag := 0;
- if (cur = 'number') or (cur = 'variable') or (cur = 'str') then begin
- res := res + (value(''));
- if cur = 'variable' then begin
- tNode := nil;
- getLL(funcList, tNode, val);
- next;
- if (tNode <> nil) and (noFuncFlag = 0) then begin
- if cur = 'brace_(' then begin
- res := res + function_arg_;
- end else begin
- res := res + '()';
- end;
- res := res + '.val';
- end;
- end else begin
- next;
- end;
- end else if cur = 'brace_(' then begin
- res := res + ('(');
- next;
- res := res + expr_(0);
- if cur = 'brace_)' then begin
- res := res + (')');
- next;
- end else begin
- write(outfile, 'error factor_ brace_)');
- error;
- end;
- end;
- factor_ := res;
- end;
- function term_(z: integer):string;
- var res : string;
- begin
- res := '';
- res := res + factor_(0);
- if (node <> nil) and ((cur = 'divide') or (cur = 'mul')) then begin
- res := res + (val);
- next;
- res := res + term_(0);
- end;
- term_ := res;
- end;
- function expr_(z: integer):string;
- var res : string;
- begin
- res := '';
- res := res + term_(0);
- if (node <> nil) and ((cur = 'minus') or (cur = 'plus')) then begin
- res := res + (val);
- next;
- res := res + expr_(0);
- end;
- expr_ := res;
- end;
- function bfactor_(z: integer):string;
- var
- res : string;
- begin
- res := '';
- if (cur = 'number') or (cur = 'variable') or (cur = 'str') then begin
- res := res + factor_(0);
- end else if cur = 'brace_(' then begin
- res := res + ('(');
- next;
- res := res + bexpr_(0);
- if cur = 'brace_)' then begin
- res := res + (')');
- next;
- end else begin
- write(outfile, 'error factor_ brace_)');
- error;
- end;
- end;
- bfactor_ := res;
- end;
- function bterm_(z: integer):string;
- var
- res : string;
- begin
- res := '';
- res := res + bfactor_(0);
- if (node <> nil) and ((cur = '<') or (cur = '<=') or (cur = '>')
- or (cur = '>=') or (cur = '<>') or (cur = '=')) then begin
- if cur = '<>' then begin
- res := res + ('!=');
- end else if cur = '=' then begin
- res := res + ('==');
- end else begin
- res := res + (val);
- end;
- next;
- res := res + bterm_(0);
- end;
- bterm_ := res;
- end;
- function bexpr_(z: integer):string;
- var
- res : string;
- begin
- res := '';
- res := res + bterm_(0);
- if (node <> nil) and ((cur = 'and') or (cur = 'or')) then begin
- if cur = 'and' then begin
- res := res + ('&&');
- end else begin
- res := res + ('||');
- end;
- next;
- res := res + bexpr_(0);
- end;
- bexpr_ := res;
- end;
- procedure writeln_;
- var
- tNode : pNodeList;
- begin
- if cur = 'brace_(' then begin
- next;
- tNode := nil;
- getLL(fileList, tNode, val);
- if tNode <> nil then begin
- js('writelnfile(' + gl + '.' + val + ', (');
- next;
- next;
- end else begin
- js('writeln((');
- end;
- js(expr_(0));
- while cur = 'comma' do begin
- js('+');
- next;
- js(expr_(0));
- end;
- if cur = 'brace_)' then begin
- jsln('));');
- next;
- semicolon_;
- end else begin
- write(outfile, 'error writeln brace_)');
- error;
- end;
- end else begin
- write(outfile, 'error writeln brace_(');
- error;
- end;
- end;
- procedure write_;
- var
- tNode : pNodeList;
- begin
- if cur = 'brace_(' then begin
- next;
- tNode := nil;
- getLL(fileList, tNode, val);
- if tNode <> nil then begin
- js('writefile(' + gl + '.' + val + ', (');
- next;
- next;
- end else begin
- js('write((');
- end;
- js(expr_(0));
- while cur = 'comma' do begin
- js('+');
- next;
- js(expr_(0));
- end;
- if cur = 'brace_)' then begin
- jsln('));');
- next;
- semicolon_;
- end else begin
- write(outfile, 'error write brace_)');
- error;
- end;
- end else begin
- write(outfile, 'error write brace_(');
- error;
- end;
- end;
- procedure initLocVar;
- var tNode : pNodeList;
- begin
- if cur = 'integer' then begin
- js('{val:0}');
- end else if (cur = 'string') or (cur = 'char') then begin
- js('{val:""}');
- end else if cur = 'variable' then begin
- tNode := nil;
- getLL(recordList, tNode, val);
- if tNode <> nil then begin
- js(gl + '.' + val + '.f({})');
- end else begin
- write(outfile, 'error var_ variable type undif but {}');
- js('{}');
- end;
- end else begin
- write(outfile, 'error var_ undif type');
- error;
- end;
- end;
- procedure function_;
- var funcName : string;
- cloneList:LinkedList;
- flag : integer;
- itClone : pNodeList;
- begin
- newLL(localVar);
- newLL(cloneList);
- funcName := val;
- addToLL(funcList, funcName, '');
- if cur = 'variable' then begin
- js(val);
- js(': { f :function(');
- next;
- if cur = 'brace_(' then begin
- next;
- while cur <> 'brace_)' do begin
- flag := 0;
- if cur = 'var' then begin
- flag := 1;
- next;
- end;
- if cur = 'variable' then begin
- js(val);
- valName := val;
- if flag = 0 then begin
- addToLL(cloneList, valName, '');
- end;
- next;
- if cur = 'colon' then begin
- next;
- if (cur = 'integer') or (cur = 'string')
- or (cur = 'variable') then begin
- valType := val;
- addToLL2(localVar, valName, valType, '');
- next;
- if cur = 'semicolon' then begin
- next;
- js(',');
- end;
- end else begin
- write(outfile, 'error function_ arg no type');
- error;
- end;
- end else begin
- write(outfile, 'error function_ arg no colon');
- error;
- end;
- end else begin
- write(outfile, 'error function_ arg no variable');
- error;
- end;
- end;
- next;
- end;
- jsln(') {');
- if cur = 'colon' then begin
- next;
- if (cur = 'integer') or (cur = 'string')
- or (cur = 'variable') then begin
- addToLL2(localVar, funcName, val, '');
- jsln('var ' + funcName + '={};');
- next;
- semicolon_;
- end else begin
- write(outfile, 'error function_ no ret type');
- error;
- end;
- end else begin
- write(outfile, 'error function_ no ret type colon');
- error;
- end;
- if cloneList.size <> 0 then begin
- itClone := cloneList.first;
- while itClone <> nil do begin
- jsln(itClone^.value + ' = {val: ' + itClone^.value + '.val};');
- nextLL(itClone);
- end;
- end;
- if cur = 'var' then begin
- next;
- count := 0;
- while cur = 'variable' do begin
- count := count + 1;
- js('var ' + val);
- valName := val;
- next;
- if cur = 'colon' then begin
- js(' = ');
- next;
- valType := val;
- addToLL2(localVar, valName, valType, '');
- initLocVar;
- jsln(';');
- next;
- semicolon_;
- end else begin
- write(outfile, 'error type_ no colon');
- error;
- end;
- end;
- if count = 0 then begin
- write(outfile, 'error type_ no variable');
- error;
- end;
- end;
- if cur = 'begin' then begin
- next;
- varBase := '';
- while (node <> nil) and (cur <> 'end') do begin
- line_;
- end;
- if node = nil then begin
- write(outfile, 'error func node nil');
- error;
- end else if cur = 'end' then begin
- next;
- semicolon_;
- end;
- jsln('return ' + funcName + ';');
- end;
- jsln('}}, //func');
- end else begin
- write(outfile, 'error function_ no name');
- error;
- end;
- localVar.size := 0;
- end;
- procedure procedure_;
- var
- funcName : string;
- cloneList:LinkedList;
- flag : integer;
- itClone : pNodeList;
- begin
- newLL(localVar);
- newLL(cloneList);
- funcName := val;
- addToLL(funcList, funcName, '');
- if cur = 'variable' then begin
- js(val);
- js(': { f :function(');
- next;
- if cur = 'brace_(' then begin
- next;
- while cur <> 'brace_)' do begin
- flag := 0;
- if cur = 'var' then begin
- flag := 1;
- next;
- end;
- if cur = 'variable' then begin
- js(val);
- valName := val;
- if flag = 0 then begin
- addToLL(cloneList, valName, '');
- end;
- next;
- if cur = 'colon' then begin
- next;
- if (cur = 'integer') or (cur = 'string')
- or (cur = 'variable') then begin
- valType := val;
- addToLL2(localVar, valName, valType, '');
- next;
- if cur = 'semicolon' then begin
- next;
- js(',');
- end;
- end else begin
- write(outfile, 'error function_ arg no type');
- error;
- end;
- end else begin
- write(outfile, 'error function_ arg no colon');
- error;
- end;
- end else begin
- write(outfile, 'error function_ arg no variable');
- error;
- end;
- end;
- next;
- end;
- jsln(') {');
- semicolon_;
- if cloneList.size <> 0 then begin
- itClone := cloneList.first;
- while itClone <> nil do begin
- jsln(itClone^.value + ' = {val: ' + itClone^.value + '.val};');
- nextLL(itClone);
- end;
- end;
- if cur = 'var' then begin
- next;
- count := 0;
- while cur = 'variable' do begin
- count := count + 1;
- js('var ' + val);
- valName := val;
- next;
- if cur = 'colon' then begin
- js(' = ');
- next;
- valType := val;
- addToLL2(localVar, valName, valType, '');
- initLocVar;
- jsln(';');
- next;
- semicolon_;
- end else begin
- write(outfile, 'error type_ no colon');
- error;
- end;
- end;
- if count = 0 then begin
- write(outfile, 'error type_ no variable');
- error;
- end;
- end;
- if cur = 'begin' then begin
- next;
- varBase := '';
- while (node <> nil) and (cur <> 'end') do begin
- line_;
- end;
- if node = nil then begin
- write(outfile, 'error func node nil');
- error;
- end else if cur = 'end' then begin
- next;
- semicolon_;
- end;
- end;
- jsln('}}, // proc');
- end else begin
- write(outfile, 'error function_ no name');
- error;
- end;
- localVar.size := 0;
- end;
- procedure uses_;
- begin
- while cur <> 'semicolon' do begin
- next;
- end;
- semicolon_;
- end;
- procedure header_;
- begin
- if cur = 'type' then begin
- next;
- type_;
- header_;
- end else if cur = 'var' then begin
- next;
- var_;
- header_;
- end else if cur = 'uses' then begin
- next;
- uses_;
- header_;
- end else if cur = 'function' then begin
- next;
- function_;
- header_;
- end else if cur = 'procedure' then begin
- next;
- procedure_;
- header_;
- end else if cur = 'forward' then begin
- next;
- semicolon_;
- header_;
- end;
- end;
- procedure assign_;
- begin
- if cur = 'assign' then begin
- js(' = (');
- next;
- js(expr_(0));
- jsln(');');
- end else begin
- write(outfile, 'error assign');
- error;
- end;
- end;
- procedure assignfile_;
- begin
- if cur = 'brace_(' then begin
- next;
- js('assignfile(' + gl + '.' + val + ', ');
- next;
- next;
- jsln('"' + val + '");');
- next;
- next;
- semicolon_;
- end else begin
- write(outfile, 'error assignfile_ brace (');
- error;
- end;
- end;
- procedure resetfile_;
- begin
- if cur = 'brace_(' then begin
- next;
- jsln('resetfile(' + gl + '.' + val + ');');
- next;
- next;
- semicolon_;
- end else begin
- write(outfile, 'error assignfile_ brace (');
- error;
- end;
- end;
- procedure closefile_;
- begin
- if cur = 'brace_(' then begin
- next;
- jsln('closefile(' + gl + '.' + val + ');');
- next;
- next;
- semicolon_;
- end else begin
- write(outfile, 'error assignfile_ brace (');
- error;
- end;
- end;
- procedure rewritefile_;
- begin
- if cur = 'brace_(' then begin
- next;
- jsln('rewritefile(' + gl + '.' + val + ');');
- next;
- next;
- semicolon_;
- end else begin
- write(outfile, 'error assignfile_ brace (');
- error;
- end;
- end;
- procedure while_;
- begin
- js('while (');
- js(bexpr_(0));
- jsln(') {');
- if cur = 'do' then begin
- next;
- if cur = 'begin' then begin
- next;
- while (node <> nil) and (cur <> 'end') do begin
- line_;
- end;
- end;
- if cur = 'end' then begin
- jsln('} // while');
- next;
- semicolon_;
- end else begin
- write(outfile, 'error while_ not end');
- error;
- end;
- end else begin
- write(outfile, 'error while_ not do');
- error;
- end;
- end;
- procedure repeat_;
- begin
- jsln('do { // repeat');
- while (node <> nil) and (cur <> 'until') do begin
- line_;
- end;
- next;
- js('} while (!(');
- js(bexpr_(0));
- semicolon_;
- jsln('));');
- end;
- procedure for_;
- var itName : string;
- begin
- js('for (');
- if cur = 'variable' then begin
- js(value('') + ' = ');
- itName := value('');
- next;
- if cur = 'assign' then begin
- next;
- if (cur = 'number') or (cur = 'variable') then begin
- js(value(''));
- next;
- if cur = 'to' then begin
- next;
- if (cur = 'number') or (cur = 'variable') then begin
- jsln('; ' + itName + ' <= ' + value('') + '; ' + itName + '++) {');
- next;
- if cur = 'do' then begin
- next;
- if cur = 'begin' then begin
- next;
- while (node <> nil) and (cur <> 'end') do begin
- line_;
- end;
- end else begin
- line_;
- end;
- if cur = 'end' then begin
- next;
- semicolon_;
- end else begin
- write(outfile, 'error for not end');
- error;
- end;
- end else begin
- write(outfile, 'error for not do');
- error;
- end;
- end;
- end else begin
- write(outfile, 'error for not assign');
- error;
- end;
- end;
- end else begin
- write(outfile, 'error for not assign');
- end;
- end else begin
- write(outfile, 'error for not variable');
- error;
- end;
- jsln('} // for');
- jsln(itName + '--;');
- end;
- procedure if_(z: Integer);
- begin
- js('if (');
- js(bexpr_(0));
- jsln(') { //if');
- if cur = 'then' then begin
- next;
- if cur = 'begin' then begin
- next;
- while (node <> nil) and (cur <> 'end') do begin
- line_;
- end;
- end;
- if cur = 'end' then begin
- jsln('} //if');
- next;
- end;
- if cur = 'semicolon' then begin
- next;
- end;
- if cur = 'else' then begin
- next;
- else_(0);
- end;
- end else begin
- write(outfile, 'error if_ not then');
- error;
- end;
- end;
- procedure else_(z:Integer);
- begin
- js(' else ');
- if cur = 'if' then begin
- next;
- if_(0);
- end else if cur = 'begin' then begin
- jsln(' { // else');
- next;
- while (node <> nil) and (cur <> 'end') do begin
- line_;
- end;
- if cur = 'end' then begin
- next;
- jsln('} // else');
- end;
- end;
- if cur = 'semicolon' then begin
- next;
- end;
- if cur = 'else' then begin
- next;
- else_(0);
- end;
- end;
- procedure readln_;
- var
- tNode : pNodeList;
- begin
- if cur = 'brace_(' then begin
- next;
- if cur = 'variable' then begin
- tNode := nil;
- getLL(fileList, tNode, val);
- if tNode <> nil then begin
- js('readlnfile(' + gl + '.' + val + ', (');
- next;
- next;
- tNode := nil;
- getLL(localVar, tNode, val);
- if (localVar.size = 0) or (tNode = nil) then begin
- varBase := gl + '.';
- end else begin
- varBase := tNode^.base;
- end;
- jsln(varBase + val + '));');
- next;
- next;
- end else begin
- js('waitReadln(');
- tNode := nil;
- getLL(localVar, tNode, val);
- if (localVar.size = 0) or (tNode = nil) then begin
- varBase := gl + '.';
- end else begin
- varBase := tNode^.base;
- end;
- js(varBase + val);
- jsln(', function(){');
- readlnCount := readlnCount + 1;
- next;
- next;
- end;
- end else begin
- writeln(outfile, 'error readln_ no variable arg');
- end;
- end else begin
- jsln('waitReadln({}, function(){');
- readlnCount := readlnCount + 1;
- end;
- next;
- end;
- function function_arg_ : string;
- var
- tNode : pNodeList;
- res : string;
- begin
- res := '';
- res := res + ('(');
- next;
- while cur <> 'brace_)' do begin
- if (cur = 'variable') and
- ((node^.next^.token = 'comma') or (node^.next^.token = 'brace_)')) then begin
- tNode := nil;
- getLL(localVar, tNode, val);
- if (localVar.size = 0) or (tNode = nil) then begin
- varBase := gl + '.';
- end else begin
- varBase := tNode^.base;
- end;
- tNode := nil;
- getLL(funcList, tNode, val);
- if (tNode <> nil) then begin
- res := res + (gl + '.funcs.' + val + '.f()');
- end else begin
- res := res + (varBase + val);
- end;
- next;
- if cur = 'comma' then begin
- res := res + (',');
- next;
- end;
- end else if (cur = 'variable') or (cur = 'str') or (cur = 'number') then begin
- res := res + ('{val:');
- res := res + (expr_(0));
- res := res + ('}');
- if cur = 'comma' then begin
- res := res + (',');
- next;
- end;
- end else begin
- write(outfile, 'error line_ no func arg');
- error;
- end;
- end;
- res := res + (')');
- next;
- function_arg_ := res;
- end;
- procedure line_;
- begin
- if cur = 'variable' then begin
- if(node^.next^.token = 'assign') then begin
- js(value('assign'));
- end else begin
- js(value('line'));
- end;
- next;
- if cur = 'assign' then begin
- assign_;
- semicolon_;
- end else if (cur = 'semicolon') then begin
- jsln('();');
- semicolon_;
- end else if cur = 'brace_(' then begin
- js(function_arg_);
- jsln(';');
- semicolon_;
- end;
- end else if cur = 'writeln' then begin
- next;
- writeln_;
- end else if cur = 'write' then begin
- next;
- write_;
- end else if cur = 'while' then begin
- next;
- while_;
- end else if cur = 'repeat' then begin
- next;
- repeat_;
- end else if cur = 'clrscr' then begin
- next;
- jsln('clrscr();');
- semicolon_;
- end else if cur = 'readln' then begin
- next;
- readln_;
- end else if cur = 'for' then begin
- next;
- for_;
- end else if cur = 'if' then begin
- next;
- if_(0);
- end else if cur = 'assign' then begin
- next;
- assignfile_;
- end else if cur = 'reset' then begin
- next;
- resetfile_;
- end else if cur = 'rewrite' then begin
- next;
- rewritefile_;
- end else if cur = 'continue' then begin
- next;
- jsln('continue;');
- semicolon_;
- end else if cur = 'close' then begin
- next;
- closefile_;
- end else if cur = 'forward' then begin
- next;
- semicolon_;
- end else if cur = 'brace_{' then begin
- js(' /* ');
- next;
- while (node <> nil) and (cur <> 'brace_}') do begin
- js(val);
- next;
- end;
- jsln(' */');
- next;
- end else begin
- write(outfile, '? line_' + val);
- error;
- end;
- end;
- procedure main_;
- var
- tNode : pNodeList;
- readlnIt : integer;
- begin
- if cur = 'begin' then begin
- varBase := 'this.';
- jsln('$main:function() {');
- next;
- tNode := funcList.first;
- while (tNode <> nil) do begin
- jsln(gl + '.funcs.' + tNode^.value + ' = pas.' + main + '.' + tNode^.value + ';');
- nextLL(tNode);
- end;
- tNode := recordVarList.first;
- while (tNode <> nil) do begin
- jsln(gl + '.' + tNode^.value + '.val = ' + gl + '.' + tNode^.token + '.f({});');
- nextLL(tNode);
- end;
- while (node <> nil) and (cur <> 'end') do begin
- line_;
- end;
- for readlnIt := 1 to readlnCount do begin
- jsln('}); // readln');
- end;
- if node = nil then begin
- write(outfile, 'error main node nil');
- error;
- end else if cur = 'end' then begin
- next;
- if cur <> 'dot' then begin
- write(outfile, 'error main no dot in finish');
- error;
- end else begin
- next;
- end;
- end else begin
- write(outfile, 'error main no end in finish');
- error;
- end;
- jsln('}');
- end else begin
- write(outfile, 'error main no start with begin');
- error;
- end;
- end;
- procedure program_;
- begin
- if cur = 'program' then begin
- next;
- if cur = 'variable' then begin
- main := val;
- gl := '$gl_' + main;
- jsln('pas.' + val + ' = {');
- next;
- end else begin
- write(outfile, 'error program no program name');
- error;
- end;
- semicolon_;
- header_;
- main_;
- jsln('}');
- jsln(gl + ' = pas.' + main + ';');
- jsln(gl + '.funcs = {};');
- end else begin
- write(outfile, 'error program_');
- error;
- end;
- if node <> nil then begin
- write(outfile, 'error program node is not nil');
- error;
- end;
- end;
- procedure start;
- begin
- varBase := '';
- newLL(funcList);
- newLL(fileList);
- newLL(localVar);
- newLL(globalVar);
- newLL(recordList);
- newLL(recordVarList);
- noFuncFlag := 0;
- program_;
- end;
- procedure openfile;
- begin
- Assign(jsfile, 'js.txt');
- Rewrite(jsfile);
- end;
- procedure closefile;
- begin
- Close(jsfile);
- end;
- begin
- clrscr;
- {writeln(sizeof(tnodelist));}
- error_count := 0;
- readlnCount := 0;
- newLL(list);
- writeln('start');
- readfile(list);
- itLL := list.first;
- Assign(Outfile, 'out.txt');
- Rewrite(Outfile);
- while itLL <> nil do begin
- writeln(Outfile, itLL^.value,' -> ', itLL^.token);
- nextLL(itLL);
- end;
- openfile;
- jsln('pas = {}');
- node := list.first;
- start;
- jsln('function main() {');
- jsln('initConsole();');
- js('pas.');
- js(main);
- jsln('.$main();');
- jsln('}');
- writeln(Outfile, 'errors: ', error_count);
- Close(Outfile);
- closefile;
- writeln('errors: ', error_count);
- writeln('finish');
- readln;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement