Plan 9 from Bell Labs’s /usr/web/sources/contrib/pdt/sky/liblex/lex.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <thread.h>
#include <bio.h>

#include "debug.h"

#include "lex.h"

int
linit(Lexer *l, int fd, State state)
{
	if((l->c=chancreate(sizeof(Tok), 2)) == nil)
		return Leof;

	if((l->bp = malloc(sizeof(Biobuf))) == nil){
		chanfree(l->c);
		return Loverflow;
	}
	if(Binit(l->bp, fd, OREAD) == Beof){
		free(l->bp);
		chanfree(l->c);
		return Leof;
	}

	l->start = l->pos = 0;
	l->cur = l->b;
	l->state = state;

	return 0;
}

void
lterm(Lexer *l)
{
	chanfree(l->c);
	Bterm(l->bp);
	free(l->bp);
}

long
lnext(Lexer *l)
{
	long c;

	if(l->pos-l->start > Ltoksize) return Loverflow;

	if((c = Bgetrune(l->bp)) == Beof) return Leof;

	l->pos++;
	*l->cur++ = c;
	return c; 
}

void
lbackup(Lexer *l)
{
	if(l->pos <= l->start) return;
	Bungetrune(l->bp);
	l->pos--;
	l->cur--;
}

long
lpeek(Lexer *l)
{
	long c;

	c = lnext(l);
	lbackup(l);

	return c;
}

void
lignore(Lexer *l)
{
	l->start = l->pos;
	l->cur = l->b;
}

int
laccept(Lexer *l, Rune *s)
{
	long c;

	if((c = lnext(l)) < 0) return 0;

	if(runestrchr(s, c) != nil) return 1;

	lbackup(l);
	return 0;
}

long
lacceptrun(Lexer *l, Rune *s)
{
	long c;
	int p, done;

	p = l->pos;
	while((c = lnext(l)) >= 0 && !(done = !runestrchr(s, c)));
	if(done) lbackup(l);

	return done ? l->pos-p : Loverflow;
}

long
lacceptuntil(Lexer *l, Rune *s)
{
	long c;
	int p, done;

	p = l->pos;
	while((c = lnext(l)) >= 0 && !(done = !!runestrchr(s, c)));
	if(done) lbackup(l);

	return done ? l->pos-p : Loverflow;
}

void
lemit(Lexer *l, int typ)
{
	Tok t;

	t.typ = typ;
	runestrncpy(t.str, l->b, l->pos-l->start);
	t.str[l->pos-l->start] = L'\0';
	lignore(l);

	send(l->c, &t);
}

Tok
lnexttok(Lexer *l)
{
	Tok t;

	while(!nbrecv(l->c, &t)) l->state = l->state.fun(l, l->state.aux);

	return t;	
}

long
llen(Lexer *l)
{
	long len;

	len = l->pos - l->start;
	return len >= 0 && len <  Ltoksize ? len : Loverflow;
}

Rune*
lestr(Lexer *l){
	Rune *s;
	long len;

	len = llen(l);
	if(len < 0) return nil;
	if((s=malloc((len+1)*sizeof(Rune))) == nil) return nil;

	runestrncpy(s, l->b, len);
	s[len] = L'\0';

	return s;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.