diff options
Diffstat (limited to 'nim/syntaxes.pas')
-rwxr-xr-x | nim/syntaxes.pas | 234 |
1 files changed, 0 insertions, 234 deletions
diff --git a/nim/syntaxes.pas b/nim/syntaxes.pas deleted file mode 100755 index 158ab8ea2..000000000 --- a/nim/syntaxes.pas +++ /dev/null @@ -1,234 +0,0 @@ -// -// -// The Nimrod Compiler -// (c) Copyright 2009 Andreas Rumpf -// -// See the file "copying.txt", included in this -// distribution, for details about the copyright. -// -unit syntaxes; - -// Implements the dispatcher for the different parsers. -{$include 'config.inc'} - -interface - -uses - nsystem, strutils, llstream, ast, astalgo, idents, scanner, options, msgs, - pnimsyn, pbraces, ptmplsyn, filters, rnimsyn; - -type - TFilterKind = (filtNone, filtTemplate, filtReplace, filtStrip); - TParserKind = (skinStandard, skinBraces, skinEndX); - -const - parserNames: array [TParserKind] of string = ('standard', 'braces', 'endx'); - filterNames: array [TFilterKind] of string = ('none', 'stdtmpl', 'replace', - 'strip'); - -type - TParsers = record - skin: TParserKind; - parser: TParser; - end; - -{@ignore} -function ParseFile(const filename: string): PNode; -{@emit -function ParseFile(const filename: string): PNode; procvar; -} - -procedure openParsers(var p: TParsers; const filename: string; - inputstream: PLLStream); -procedure closeParsers(var p: TParsers); -function parseAll(var p: TParsers): PNode; - -function parseTopLevelStmt(var p: TParsers): PNode; -// implements an iterator. Returns the next top-level statement or nil if end -// of stream. - - -implementation - -function ParseFile(const filename: string): PNode; -var - p: TParsers; - f: TBinaryFile; -begin - if not OpenFile(f, filename) then begin - rawMessage(errCannotOpenFile, filename); - exit - end; - OpenParsers(p, filename, LLStreamOpen(f)); - result := ParseAll(p); - CloseParsers(p); -end; - -function parseAll(var p: TParsers): PNode; -begin - case p.skin of - skinStandard: result := pnimsyn.parseAll(p.parser); - skinBraces: result := pbraces.parseAll(p.parser); - skinEndX: InternalError('parser to implement'); - // skinEndX: result := pendx.parseAll(p.parser); - end -end; - -function parseTopLevelStmt(var p: TParsers): PNode; -begin - case p.skin of - skinStandard: result := pnimsyn.parseTopLevelStmt(p.parser); - skinBraces: result := pbraces.parseTopLevelStmt(p.parser); - skinEndX: InternalError('parser to implement'); - //skinEndX: result := pendx.parseTopLevelStmt(p.parser); - end -end; - -function UTF8_BOM(const s: string): int; -begin - if (s[strStart] = #239) and (s[strStart+1] = #187) - and (s[strStart+2] = #191) then result := 3 - else result := 0 -end; - -function containsShebang(const s: string; i: int): bool; -var - j: int; -begin - result := false; - if (s[i] = '#') and (s[i+1] = '!') then begin - j := i+2; - while s[j] in WhiteSpace do inc(j); - result := s[j] = '/' - end -end; - -function parsePipe(const filename: string; inputStream: PLLStream): PNode; -var - line: string; - s: PLLStream; - i: int; - q: TParser; -begin - result := nil; - s := LLStreamOpen(filename, fmRead); - if s <> nil then begin - line := LLStreamReadLine(s) {@ignore} + #0 {@emit}; - i := UTF8_Bom(line) + strStart; - if containsShebang(line, i) then begin - line := LLStreamReadLine(s) {@ignore} + #0 {@emit}; - i := strStart; - end; - if (line[i] = '#') and (line[i+1] = '!') then begin - inc(i, 2); - while line[i] in WhiteSpace do inc(i); - OpenParser(q, filename, LLStreamOpen(ncopy(line, i))); - result := pnimsyn.parseAll(q); - CloseParser(q); - end; - LLStreamClose(s); - end -end; - -function getFilter(ident: PIdent): TFilterKind; -var - i: TFilterKind; -begin - for i := low(TFilterKind) to high(TFilterKind) do - if IdentEq(ident, filterNames[i]) then begin - result := i; exit - end; - result := filtNone -end; - -function getParser(ident: PIdent): TParserKind; -var - i: TParserKind; -begin - for i := low(TParserKind) to high(TParserKind) do - if IdentEq(ident, parserNames[i]) then begin - result := i; exit - end; - rawMessage(errInvalidDirectiveX, ident.s); -end; - -function getCallee(n: PNode): PIdent; -begin - if (n.kind = nkCall) and (n.sons[0].kind = nkIdent) then - result := n.sons[0].ident - else if n.kind = nkIdent then result := n.ident - else rawMessage(errXNotAllowedHere, renderTree(n)); -end; - -function applyFilter(var p: TParsers; n: PNode; const filename: string; - input: PLLStream): PLLStream; -var - ident: PIdent; - f: TFilterKind; -begin - ident := getCallee(n); - f := getFilter(ident); - case f of - filtNone: begin - p.skin := getParser(ident); - result := input - end; - filtTemplate: result := filterTmpl(input, filename, n); - filtStrip: result := filterStrip(input, filename, n); - filtReplace: result := filterReplace(input, filename, n); - end; - if f <> filtNone then begin - if gVerbosity >= 2 then begin - rawMessage(hintCodeBegin); - messageOut(result.s); - rawMessage(hintCodeEnd); - end - end -end; - -function evalPipe(var p: TParsers; n: PNode; const filename: string; - start: PLLStream): PLLStream; -var - i: int; -begin - result := start; - if n = nil then exit; - if (n.kind = nkInfix) and (n.sons[0].kind = nkIdent) - and IdentEq(n.sons[0].ident, '|'+'') then begin - for i := 1 to 2 do begin - if n.sons[i].kind = nkInfix then - result := evalPipe(p, n.sons[i], filename, result) - else - result := applyFilter(p, n.sons[i], filename, result) - end - end - else if n.kind = nkStmtList then - result := evalPipe(p, n.sons[0], filename, result) - else - result := applyFilter(p, n, filename, result) -end; - -procedure openParsers(var p: TParsers; const filename: string; - inputstream: PLLStream); -var - pipe: PNode; - s: PLLStream; -begin - p.skin := skinStandard; - pipe := parsePipe(filename, inputStream); - if pipe <> nil then - s := evalPipe(p, pipe, filename, inputStream) - else - s := inputStream; - case p.skin of - skinStandard, skinBraces, skinEndX: - pnimsyn.openParser(p.parser, filename, s); - end -end; - -procedure closeParsers(var p: TParsers); -begin - pnimsyn.closeParser(p.parser); -end; - -end. |