mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 21:51:42 +02:00
[PATCH 035/188] adding parser
From 287588a80cd263eba59e38de6fdafb48511a86e0 Mon Sep 17 00:00:00 2001 From: Dmitry Boyarintsev <skalogryz.lists@gmail.com> Date: Wed, 20 Nov 2019 00:31:34 -0500 git-svn-id: branches/wasm@46031 -
This commit is contained in:
parent
f7ae46356b
commit
3a3d299599
@ -5,7 +5,7 @@ unit watparser;
|
||||
interface
|
||||
|
||||
uses
|
||||
SysUtils, Classes, parseutils, wasmtext;
|
||||
SysUtils, Classes, parseutils, wasmtext, wasmmodule, wasmbin;
|
||||
|
||||
type
|
||||
TWatToken = (weNone, weError,
|
||||
@ -40,6 +40,8 @@ type
|
||||
resText : string;
|
||||
procedure SetSource(const abuf: string);
|
||||
function Next: Boolean;
|
||||
|
||||
function GetInt32: Integer;
|
||||
end;
|
||||
|
||||
const
|
||||
@ -79,6 +81,18 @@ const
|
||||
|
||||
function ScanString(const buf: string; var idx: integer): string;
|
||||
|
||||
|
||||
type
|
||||
TParseResult = record
|
||||
error : string;
|
||||
end;
|
||||
|
||||
//function ConsumeToken(sc: TWatScanner; tk: TWatToken): Boolean;
|
||||
function ParseModule(sc: TWatScanner; dst: TWasmModule; var res: TParseResult): Boolean;
|
||||
procedure ErrorUnexpected(var res: TParseResult; const tokenstr: string = '');
|
||||
procedure ErrorExpectButFound(var res: TParseResult; const expected: string; const butfound: string = '');
|
||||
procedure ErrorUnexpectedEof(var res: TParseResult);
|
||||
|
||||
implementation
|
||||
|
||||
procedure GetGrammar(const txt: string; out entity: TWatToken; out instByte: byte);
|
||||
@ -240,4 +254,181 @@ begin
|
||||
resText := Copy(buf, ofs, idx-ofs);
|
||||
end;
|
||||
|
||||
function TWatScanner.GetInt32: Integer;
|
||||
var
|
||||
err: integer;
|
||||
begin
|
||||
Val(resText, Result, err);
|
||||
if err<>0 then Result:=0;
|
||||
end;
|
||||
|
||||
function ConsumeOpenToken(sc: TWatScanner; tk: TWatToken): Boolean;
|
||||
begin
|
||||
sc.Next;
|
||||
Result := (sc.token=weOpenBrace) or (sc.Token=tk);
|
||||
if Result and (sc.token=weOpenBrace) then begin
|
||||
sc.Next;
|
||||
Result := (sc.Token=tk);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ConsumeToken(sc: TWatScanner; tk: TWatToken; var res: TParseResult): Boolean;
|
||||
begin
|
||||
Result:=sc.token =tk;
|
||||
if not Result then
|
||||
ErrorExpectButFound(res, 'some token','?')
|
||||
else
|
||||
sc.Next;
|
||||
end;
|
||||
|
||||
function ParseNumOfId(sc: TWatScanner; out num: integer; out id: string; var res: TParseResult): Boolean;
|
||||
begin
|
||||
num:=-1;
|
||||
id:='';
|
||||
Result := sc.Next;
|
||||
if not Result then begin
|
||||
ErrorUnexpectedEof(res);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
case sc.token of
|
||||
weNumber: num:=sc.GetInt32;
|
||||
weIdent: id:=sc.resText;
|
||||
else
|
||||
ErrorExpectButFound(res, 'index');
|
||||
Result := false;
|
||||
end;
|
||||
Result := true;
|
||||
if Result then sc.Next;
|
||||
end;
|
||||
|
||||
function TokenTypeToValType(t: TWatToken; out tp: byte): Boolean;
|
||||
begin
|
||||
Result:=true;
|
||||
case t of
|
||||
wei32: tp:=valtype_i32;
|
||||
wei64: tp:=valtype_i64;
|
||||
wef32: tp:=valtype_f32;
|
||||
wef64: tp:=valtype_f64;
|
||||
else
|
||||
tp:=0;
|
||||
Result:=false;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ParseParam(sc: TWatScanner; out id: string; out tp: byte; var res: TParseResult): Boolean;
|
||||
begin
|
||||
tp:=0;
|
||||
id:='';
|
||||
if sc.token=weParam then sc.Next;
|
||||
|
||||
if sc.token=weIdent then begin
|
||||
id:=sc.resText;
|
||||
sc.Next;
|
||||
end;
|
||||
|
||||
if not TokenTypeToValType(sc.token, tp) then begin
|
||||
ErrorExpectButFound(res, 'type');
|
||||
Result:=false;
|
||||
Exit;
|
||||
end else
|
||||
Result:=true;
|
||||
sc.Next;
|
||||
Result := sc.token=weCloseBrace;
|
||||
if Result then sc.Next
|
||||
else ErrorExpectButFound(res, ')');
|
||||
end;
|
||||
|
||||
function ParseFunc(sc: TWatScanner; dst: TWasmFunc; var res: TParseResult): Boolean;
|
||||
var
|
||||
nm : integer;
|
||||
id : string;
|
||||
p : TWasmParam;
|
||||
begin
|
||||
if sc.token=weFunc then sc.Next;
|
||||
repeat
|
||||
if sc.token=weIdent then begin
|
||||
dst.id:=sc.resText;
|
||||
sc.Next;
|
||||
end;
|
||||
|
||||
Result:=false;
|
||||
if sc.token=weOpenBrace then begin
|
||||
sc.Next;
|
||||
case sc.token of
|
||||
weType: begin
|
||||
if not ParseNumOfId(sc, nm, id, res) then Exit;
|
||||
if nm>=0 then dst.typeIdx:=nm
|
||||
else dst.typeId:=id;
|
||||
end;
|
||||
weParam: begin
|
||||
sc.Next;
|
||||
p:=dst.GetInlineType.AddParam;
|
||||
if not ParseParam(sc, p.id, p.tp, res) then Exit;
|
||||
end;
|
||||
weResult: begin
|
||||
sc.Next;
|
||||
p:=dst.GetInlineType.AddResult;
|
||||
if not ParseParam(sc, p.id, p.tp, res) then Exit;
|
||||
end;
|
||||
weLocal: begin
|
||||
sc.Next;
|
||||
p:=dst.AddLocal;
|
||||
if not ParseParam(sc, p.id, p.tp, res) then Exit;
|
||||
end;
|
||||
else
|
||||
ErrorUnexpected(res, 'booh');
|
||||
Exit;
|
||||
end;
|
||||
if not ConsumeToken(sc, weCloseBrace, res) then Exit;
|
||||
end;
|
||||
|
||||
until sc.token=weCloseBrace;
|
||||
sc.Next;
|
||||
end;
|
||||
|
||||
function ParseModule(sc: TWatScanner; dst: TWasmModule; var res: TParseResult): Boolean;
|
||||
begin
|
||||
if not ConsumeOpenToken(sc, weModule) then begin
|
||||
Result := false;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
repeat
|
||||
sc.Next;
|
||||
if sc.token=weOpenBrace then begin
|
||||
sc.Next;
|
||||
|
||||
if sc.token = weFunc then begin
|
||||
Result := ParseFunc(sc, dst.AddFunc, res);
|
||||
if not Result then Exit;
|
||||
end;
|
||||
|
||||
end else if sc.token<>weCloseBrace then begin
|
||||
ErrorUnexpected(res);
|
||||
Result := false;
|
||||
exit;
|
||||
end;
|
||||
|
||||
until sc.token=weCloseBrace;
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
procedure ErrorUnexpected(var res: TParseResult; const tokenstr: string);
|
||||
begin
|
||||
res.error:='unexpected token '+tokenstr;
|
||||
end;
|
||||
|
||||
procedure ErrorUnexpectedEof(var res: TParseResult);
|
||||
begin
|
||||
res.error:='unexpected end of file';
|
||||
end;
|
||||
|
||||
procedure ErrorExpectButFound(var res: TParseResult; const expected, butfound: string);
|
||||
begin
|
||||
res.error:=expected +' is expected';
|
||||
if butfound<>'' then
|
||||
res.error:=res.error+', but '+butfound+ ' found';
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user