⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 untcompile.pas

📁 运用delphi编写的小型解释器
💻 PAS
📖 第 1 页 / 共 3 页
字号:
         ocMul: begin
                v1 := Stack.Pop;
                v2 := Stack.Pop;
                Stack.Put(v2 * v1);
                end;

         ocDiv: begin
                v1 := Stack.Pop;
                v2 := Stack.Pop;
                Stack.Put(v2 / v1);
                end;

         ocEqual: begin
                  v1 := Stack.Pop;
                  v2 := Stack.Pop;
                  Stack.Put(v1 = v2);
                  end;

         ocGreater: begin
                    v2 := Stack.Pop;
                    v1 := Stack.Pop;
                    Stack.Put(v1 > v2);
                    end;

         ocGreaterEqual: begin
                         v2 := Stack.Pop;
                         v1 := Stack.Pop;
                         Stack.Put(v1 >= v2);
                         end;

         ocLess: begin
                 v2 := Stack.Pop;
                 v1 := Stack.Pop;
                 Stack.Put(v1 < v2);
                 end;

         ocLessEqual: begin
                      v2 := Stack.Pop;
                      v1 := Stack.Pop;
                      Stack.Put(v1 <= v2);
                      end;

         ocNotEqual: begin
                     v2 := Stack.Pop;
                     v1 := Stack.Pop;
                     Stack.Put(v1 <> v2);
                     end;

         ocIfFalseGoto: begin
                        v2 := Stack.Pop;
                        if not v2 then
                            begin
                            i := p2;
                            continue;
                            end;

                        end;

         ocGoto: begin
                 i := p2;
                 continue; 
                 end;

           else raise Exception.Create('未知命令!');
         end;

    Inc(i);

    end;

end;

function TCompile.getPCode: string;
begin
  Result := FProgList.getText;
end;

function TCompile.getConsts: string;
begin
  Result := FConsts.getText;
end;

function TCompile.ProcDef: integer;
var
  aProcName: string;
  aIdent, rIdent: TIdent;
  astr: string;
begin
  getIdentifier;

  aProcName := FCurToken.Data;

  aIdent := FVariables.Add(aProcName);

  aIdent.FIdentType := itFunction;

  if NextToken.ID = idOpenbracket then
      begin
      getOpenBracket;
      ProcParam(aProcName);
      getCloseBracket;
      end;

  if NextToken.id = id2points then
    begin
    ReadToken;

    getVarType;

    rIdent := FVariables.Add(genVarName(aProcName, 'Result'));
    rIdent.DataType := FCurToken.Data;
    end;

  getDelimeter;

  Result := aIdent.ID;
end;

procedure TCompile.ProcParam(aProcName: string);
var
  i, j: integer;
  pIdent, vIdent: TIdent;
begin
  pIdent := FVariables.getIdentByName(aProcName);
  
  while true do
    begin
    ReadToken;

    if FCurToken.ID <> idIdentifier then raiseError('期望变量!');

    if FVariables.IndexOf(genVarName(aProcName, FCurToken.Data)) >= 0 then raiseError(FCurToken.data + '变量重复声明!');

    i := FVariables.Count;

    vIdent := FVariables.Add(genVarName(aProcName, FCurToken.Data));

    pIdent.AddParam(vIdent);
    
    while NextToken.ID = idComma do
        begin
        ReadToken;

        ReadToken;

        if FCurToken.ID <> idIdentifier then raiseError('期望变量!');
        if FVariables.IndexOf(genVarName(aProcName, FCurToken.Data)) >= 0 then raiseError(FCurToken.data + '变量重复声明!');

        vIdent := FVariables.Add(genVarName(aProcName, FCurToken.Data));

        pIdent.AddParam(vIdent);
        end;

    if NextToken.ID = id2Points then
        begin
        ReadToken;
        getVarType;

        for j := i to FVariables.Count - 1 do
            begin
            FVariables.Idents[j].FDataType := getDataType(FCurToken.Data);
            end;

        if NextToken.id <> idCloseBracket then getDelimeter;
        end;

    if (NextToken.ID <= idReservedEnd) and (NextToken.ID >= idReservedBase) then exit;
    end;

end;

function TCompile.genVarName(aPreFix, aName: string): string;
begin
  if aPreFix = '' then Result := aName
    else Result := aPreFix + '.' + aName;

end;

procedure TCompile.ProcBody(aID: integer);
var
  pIdent: TIdent;
begin
  pIdent := FVariables.getIdentByID(aID);

  Declarations(pIdent.Name);
  Statement(pIdent.Name);;
  
end;

function TCompile.getVariableByName(aName: string): TIdent;
var
  i, j, l, k: integer;
begin
  repeat
    i := FVariables.IndexOf(aName);
    if i >= 0 then
      begin
      Result := FVariables.getIdentByIndex(i);
      exit;
      end;

    l := Length(aName);
    
    for j := l downto 1 do
      begin
      if aName[j] = '.' then
           begin
           for k := j - 1 downto 1 do
             begin
             if aName[k] = '.' then break;
             end;

           if k = 0 then aName := RightStr(aName, l - j)
               else aName := LeftStr(aName, k) + RightStr(aName, l - j);

           break;
           end;
      end;

    if j = 0 then aName := '';

  until aName <> '';

end;

function TCompile.getVariableByName(aPreFix, aName: string): TIdent;
begin
  Result := getVariableByName(genVarName(aPreFix, aName));
end;

{ TWordList }

procedure TWordList.AddWord(aWordName: String; aWordID: integer);
begin
  FList.AddObject(aWordName, TObject(aWordID));
  Inc(FCount);
end;

constructor TWordList.Create;
begin
  FList := TStringList.Create;
  FList.CaseSensitive := false;

  FCount := 0;
end;

destructor TWordList.Destroy;
begin
  FreeAndNil(FList);
end;

function TWordList.GetWordID(aWordName: string): integer;
var
  i: integer;
begin
  Result := -1;

  for i := 0 to FList.Count - 1 do
    begin
    if SameText(FList.Strings[i], aWordName) then
        begin
        Result := Integer(FList.Objects[i]);
        exit;
        end;
    end;

  inherited;
end;

function TWordList.GetWordName(aWordID: integer): string;
var
  i: integer;
begin
  Result := '';

  for i := 0 to FList.Count do
    begin
    if Integer(FList.Objects[i]) = aWordID then
        begin
        Result := FList.Names[i];
        exit;
        end;
    end;

end;

{ TConsts }

function TDynaWords.AddWord(aWordName: String): integer;
begin
  Inc(FConstID);

  inherited AddWord(aWordName, FConstID);

  Result := FConstID; 
end;

constructor TDynaWords.Create;
begin
  inherited;
  FConstID := 0;
end;

{ TResWords }

procedure TResWords.AddWord(aWordName: String; aWordID: integer);
begin
  inherited;
end;

{ TResConsts }

procedure TResConsts.AddWord(aWordName: String; aWordID: integer);
begin
  inherited;
end;


{ TProgList }

constructor TProgList.Create;
begin
  setLength(FProgList, 100);
  FCount := 0;
end;

destructor TProgList.Destroy;
begin
  setLength(FProgList, 0);
  
  inherited;
end;

function TProgList.getText: string;
var
  i: integer;
  aStr: string;
begin
  Result := '';

  for i := 0 to FCount - 1 do
    begin
    aStr := getPCodeName(FProgList[i].Cmd);

    if Length(aStr) < 10 then aStr := aStr + DupeString(' ', 10 - Length(aStr));

    Result := Result + '[' + IntToStr(i) + ']' + aStr + '  ' + 
              IntToStr(FProgList[i].P1) + ', ' + IntToStr(FProgList[i].P2) + #13#10;
    end;

end;

function TProgList.PutCode(aCmd, aP1, aP2: integer): integer;
begin
  if FCount >= Length(FProgList) then
    begin
    setLength(FProgList, FCount + 100);
    end;

  FProgList[FCount].Cmd := aCmd;
  FProgList[FCount].P1 := aP1;
  FProgList[FCount].P2 := aP2;

  Result := FCount;
  
  Inc(FCount);
end;

{ TIdent }

procedure TIdent.AddParam(aIdent: TIdent);
begin
  FParams.AddObject(aIdent.Name, aIdent);
  aIdent.OffPos := FParams.Count - 1;
  aIdent.DynaFlag := True;
end;

constructor TIdent.Create;
begin
  FParams := TStringList.Create;
  FDynaFlag := false;
end;

destructor TIdent.Destroy;
begin
  FreeAndNil(FParams);

  inherited;
end;

{ TIdentList }

function TIdentList.Add(aName: string; aID: Integer): TIdent;
begin
  if FCount >= Length(FIdents) then
      begin
      setLength(FIdents, FCount + 30);
      end;

  FIdents[FCount] := TIdent.Create;
  FIdents[FCount].Name := aName;
  FIdents[FCount].ID := aID;

  Result := FIdents[FCount];
  
  Inc(FCount);
end;

constructor TIdentList.Create;
begin
  FCount := 0;
  setLength(FIdents, 30);
end;

destructor TIdentList.Destroy;
begin
  FCount := 0;
  setLength(FIdents, 0);
  
  inherited;
end;

function TIdentList.getIdentByID(aID: integer): TIdent;
var
  i: integer;
begin
  for i := 0 to FCount - 1 do
    begin
    if FIdents[i].ID = aID then
         begin
         Result := FIdents[i];
         exit;
         end;
    end;

  raise Exception.Create('没有ID为' + IntToStr(aID) + '的变量!');

end;

function TIdentList.getIdentByIndex(aIndex: integer): TIdent;
begin

  if (aIndex < 0) or (aIndex >= FCount) then raise Exception.Create('索引超出范围!');

  Result := FIdents[aIndex];

end;

function TIdentList.getIdentByName(aName: String): TIdent;
var
  i: integer;
begin
  i := IndexOf(aName);

  if i < 0 then raise Exception.Create('没有名为' + aName + '的标识符!');

  Result := FIdents[i];
end;

function TIdentList.getText: string;
var
  i: integer;
  astr: string;
begin
  Result := '';

  for i := 0 to Count - 1 do
    begin
    if VarIsNull(FIdents[i].FValue) then astr := 'null'
      else astr := FIdents[i].FValue;

    Result := Result + '[' + IntToStr(i) + '] Name = ' + FIdents[i].FName +
              '; Value = ' + astr + '; ID = ' + IntToStr(FIdents[i].ID) +
              #13#10;
    end;

end;

function TIdentList.IndexOf(aName: string): integer;
var
  i: integer;
begin
  Result := -1;
  
  for i := 0 to FCount - 1 do
    begin
    if SameText(FIdents[i].Name, aName) then
         begin
         Result := i;
         exit;
         end;
    end;

end;

procedure TIdentList.SetValue(aID: integer; aValue: variant);
var
  i: integer;
begin
  for i := 0 to FCount - 1 do
    begin
    if FIdents[i].ID = aID then
        begin
        FIdents[i].Value := aValue;
        exit;
        end;
    end;

  raise Exception.Create('找不到ID为' + IntToStr(aID) + '变量!');

end;

{ TConstList }

function TConstList.Add(aName: string): TIdent;
begin
  Inc(FConstID);

  Result := inherited Add(aName, FConstID);
end;

constructor TConstList.Create;
begin
  inherited;

  FConstID := 0;
end;

{ TVariableList }

function TVariableList.Add(aName: string): TIdent;
begin
  Inc(FID);
  
  Result := inherited add(aName, FID);
end;

constructor TVariableList.Create;
begin
  FID := 0;
end;

{ TStack }

procedure TStack.Clear;
begin
  FCount := 0;
  setLength(FDatas, 30);  
end;

constructor TStack.Create;
begin
  setLength(FDatas, 100);
  FCount := 0;
end;

destructor TStack.Destroy;
begin
  setLength(FDatas, 0);
  
  inherited;
end;

function TStack.getData(aIndex: integer): variant;
begin
  if aIndex < 0 then raise Exception.Create('参数不应小于0!');
  if aIndex >= FCount then raise Exception.Create('参数大于堆栈上限!');

  Result := FDatas[aIndex];
end;

function TStack.Pop: variant;
begin
  if FCount = 0 then raise Exception.Create('堆栈下溢出!');

  Result := FDatas[FCount - 1];

  Dec(FCount);
end;

procedure TStack.Put(v: Variant);
begin
  if FCount >= Length(FDatas) then
    begin
    setLength(FDatas, FCount + 100);
    end;

  FDatas[FCount] := v;

  Inc(FCount);
end;

initialization
  ResWords := TResWords.Create;
  ResConsts := TResConsts.Create;
  Stack := TStack.Create;

  ResWords.AddWord('program', idProgram);
  ResWords.AddWord('label', idLabel);
  ResWords.AddWord('goto', idGoto);
  ResWords.AddWord('var', idVar);
  ResWords.AddWord('begin', idBegin);
  ResWords.AddWord('end', idEnd);;
  ResWords.AddWord('and', idAnd);
  ResWords.AddWord('or', idOr);
  ResWords.AddWord('xor', idXor);
  ResWords.AddWord('not', idNot);
  ResWords.AddWord('shl', idShl);
  ResWords.AddWord('shr', idShr);
  ResWords.AddWord('div', idDiv);
  ResWords.AddWord('mod', idMod);
  ResWords.AddWord('true', idTrue);
  ResWords.AddWord('false', idFalse);
  ResWords.AddWord('if', idIf);
  ResWords.AddWord('then', idThen);
  ResWords.AddWord('else', idElse);
  ResWords.AddWord('while', idWhile);
  ResWords.AddWord('repeat', idRepeat);
  ResWords.AddWord('until', idUntil);
  ResWords.AddWord('for', idFor);
  ResWords.AddWord('to', idTo);
  ResWords.AddWord('downto', idDownto);
  ResWords.AddWord('do', idDo);
  ResWords.AddWord('nil', idNil);
  ResWords.AddWord('null', idNull);
  ResWords.AddWord('Unitinit', idUnitinit);
  ResWords.AddWord('Unitfinal', idUnitfinal);
  ResWords.AddWord('class', idClass);
  ResWords.AddWord('type', idType);
  ResWords.AddWord('constr', idConstr);
  ResWords.AddWord('destr', idDestr);
  Reswords.AddWord('uses', idUses);
  ResWords.AddWord('unit', idUnit);
  ResWords.AddWord('interface', idInterface);
  ResWords.AddWord('implement', idImplement);
  ResWords.AddWord('procedure', idProcedure);
  ResWords.AddWord('private', idPrivate);
  ResWords.AddWord('public', idPublic);
  ResWords.AddWord('protected', idProtected);
  ResWords.AddWord('published', idPublished);
  ResWords.AddWord('function', idFunction);
  ResWords.AddWord('const', idConst);
  ResWords.AddWord('property', idProperty);
  ResWords.AddWord('virtual', idVirtual);
  ResWords.AddWord('override', idOverride);
  ResWords.AddWord('dynamic', idDynamic);
  ResWords.AddWord('record', idRecord);
  ResWords.AddWord('forward', idForward);
  ResWords.AddWord('index', idIndex);
  ResWords.AddWord('read', idRead);
  ResWords.AddWord('write', idWrite);
  ResWords.AddWord('stored', idStored);
  ResWords.AddWord('default', idDefault);
  ResWords.AddWord('abstract', idAbstract);
  ResWords.AddWord('stdcall', idStdcall);



finalization
  FreeAndNil(ResWords);
  FreeAndNil(ResConsts);
  
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -