#############################################################################
##
#W  parse.gi           OpenMath Package         Andrew Solomon
##
#H  @(#)$Id: parse.gi,v 1.5 2006/01/27 14:55:55 gap Exp $
##
#Y  Copyright (C)  1997,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
#Y  (C) 1998 School Math and Comp. Sci., University of St.  Andrews, Scotland
##
##  The parser reads token/values off the stream and builds GAP objects.
##  

Revision.("openmath/gap/parse.gi") :=
    "@(#)$Id: parse.gi,v 1.5 2006/01/27 14:55:55 gap Exp $";



InstallGlobalFunction(OMgetObjectByteStream,
function(inputstream)
	local stream;

	stream := OMinstreamCreate(inputstream);
	return OMparseStart(stream);
end);

InstallGlobalFunction(OMparseStart , function(stream)
	# Start -> OMtokenObject object OMtokenEndObject

	local obj;

	# get the OMtokenObject
	OMgetToken(stream, OMtokenObject);

	# parse the object
	obj := OMparseObject(stream);

	OMgetToken(stream, OMtokenEndObject);

	return obj;
end);


InstallGlobalFunction(OMparseApplication, function(stream)
		local head, rest, nextob;

		# first get the OMtokenApp off the stream
		OMgetToken(stream, OMtokenApp);

		#
		# 1. Get the "head" object
		# the possibilities are:
		#
		# 2. Apply the head to the rest with OMApply(head, rest);
		#

		# 1.1 If it's a symbol, look it up and see what it translates to in GAP
		if OMnextToken(stream) = OMtokenSymbol then
			head := OMsymLookup(OMgetSymbol(stream));
		else
			head := OMparseObject(stream);
		fi;

		# get the rest
		rest := [];
		while OMnextToken(stream) <> OMtokenEndApp do
			nextob := OMparseObject(stream);
			Append(rest, [nextob]);
		od;

		# finally get the OMtokenEndApp off the stream
		OMgetToken(stream, OMtokenEndApp);


		return OMgapApply(head, rest);
end);

# just ignore everything but the object
InstallGlobalFunction(OMparseAttribution, function(stream)
		local nextob, ob;

		# first get the OMtokenAttr off the stream
		OMgetToken(stream, OMtokenAttr);

		# now get the OMtokenAtp off the stream
		OMgetToken(stream, OMtokenAtp);

		# just read all the objects until the end of attribution
		while OMnextToken(stream) <> OMtokenEndAtp do
			nextob := OMparseObject(stream);
		od;

		# get the OMtokenEndAtp off the stream
		OMgetToken(stream, OMtokenEndAtp);

		# finally, the only thing we don't ignore - the unattributed object
		ob :=  OMparseObject(stream);

		OMgetToken(stream, OMtokenEndAttr);

		return ob;
end);


InstallGlobalFunction(OMparseBind, function(stream)
	Error("Binding is unimplemented");
end);

InstallGlobalFunction(OMparseObject, function(stream)
##
## Object -> symbol | variable | integer | float | string | bytearray | 
##           application | binding | error | attribution
	local obj;

	# first the basic objects

	if OMnextToken(stream) = OMtokenSymbol then
		# this is just a nullary symbol which we hope is a GAP object
		return OMnullarySymbolToGAP(OMgetSymbol(stream));
	elif OMnextToken(stream) = OMtokenVar then
		return OMgetVar(stream);
	elif  OMnextToken(stream) = OMtokenInteger then
		return OMgetInteger(stream);
	elif OMnextToken(stream) = OMtokenFloat then
		Error("GAP doesn't support floating point numbers.");
	elif OMnextToken(stream) = OMtokenString then
		return OMgetString(stream);
	elif OMnextToken(stream) = OMtokenByteArray then
		Error("GAP doesn't support byte arrays.");

	# now the compound objects
	elif OMnextToken(stream) = OMtokenApp then
		return OMparseApplication(stream);
	elif OMnextToken(stream) = OMtokenBind then
		return OMparseBind(stream);
	elif OMnextToken(stream) = OMtokenError then
		Error("OMtokenError encountered");
	elif OMnextToken(stream) = OMtokenAttr then
		return OMparseAttribution(stream);
		
		
	else
		Error("unrecognized token");
	fi;
end);

#############################################################################
##

