Menu

[r9]: / trunk / src / Source.pas  Maximize  Restore  History

Download this file

139 lines (124 with data), 3.3 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
unit Source;
interface
uses
Global;
type
TSource=class
Handle :TextFile; // source file
Line :integer; // current line
Index :integer; // current char in line
Src :string; // current readed line
SrcToken :string; // current token
LastChar :char; // last readed char
NextChar :char; // current readed char (next in token)
Token :string; // current token (uppercase for keywords, without quotes for litteral strings)
constructor Create(const FileName:string);
destructor Destroy; override;
function StrToInt(const Str:string):integer;
function BitsCount(const Str:string):integer;
procedure Error(const Msg:string);
function ReadChar:char;
function SkipChar(c:char):boolean;
function StringConst:string;
function AsciiChar:string;
end;
implementation
constructor TSource.Create(const FileName:string);
begin
AssignFile(Handle,FileName);
Reset(Handle);
Src :='';
Line :=1;
Index:=0;
NextChar:=' ';
ReadChar;
end;
destructor TSource.Destroy;
begin
CloseFile(Handle);
end;
// convert Str to an integer
function TSource.StrToInt(const Str:string):integer;
var
e:integer;
begin
Val(Str,Result,e);
if e>0 then Error('Invalid number '+str);
end;
// how many bits to store this numeric ?
function TSource.BitsCount(const Str:string):integer;
begin
case Length(Str) of
0 : Error('Invalid number');
1..2 : Result:=8;
3 : if StrLess(Str,'255') then Result:=8 else Result:=16;
4 : Result:=16;
5 : if StrLess(Str,'65535') then Result:=16 else Result:=32;
else if StrLess(Str,'4294967295') then Result:=32 else Error('cardinal overflow');
end;
end;
procedure TSource.Error(const Msg:string);
var
i:integer;
begin
WriteLn('Error on line ',line,' at char ',index,' on ',SrcToken);
WriteLn(Src);
for i:=1 to Index-Length(SrcToken)-1 do Write(' ');
for i:=1 to Length(SrcToken) do Write('^');
WriteLn;
WriteLn(Msg);
ReadLn;
Halt;
end;
// read one char
function TSource.ReadChar:char;
begin
if NextChar=#27 then Error('Unexpected end of file');
SrcToken:=SrcToken+NextChar;
LastChar:=NextChar;
Result:=NextChar;
if Eof(Handle) then NextChar:=#27 else Read(Handle,NextChar);
{$IFDEF LOG}Write(NextChar);{$ENDIF}
if NextChar=#13 then inc(Line) else
if NextChar=#10 then Index:=0 else begin
inc(Index);
if Index=1 then Src:=NextChar else Src:=Src+NextChar;
end;
end;
// skip one char ?
function TSource.SkipChar(c:char):boolean;
begin
Result:=NextChar=c;
if Result then ReadChar;
end;
// read a quoted string
function TSource.StringConst:string;
var
done:boolean;
begin
ReadChar; // ''''
Result:='';
repeat
while NextChar<>'''' do begin
if NextChar=#13 then Error('Open string');
Result:=Result+ReadChar;
end;
ReadChar; // ''''
if NextChar='''' then begin
Result:=Result+ReadChar;
done:=False;
end else begin
done:=True;
end;
until done;
end;
// read an ascii char value (#xxx)
function TSource.AsciiChar:string;
begin
ReadChar; // #
Result:='';
while NextChar in ['0'..'9'] do Result:=Result+ReadChar;
if BitsCount(Result)>8 then Error('byte overflow');
Result:=chr(StrToInt(Result));
end;
end.
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.