private void CompileTerm()
{
if (this.TryCompileToken(TokenType.Operator, "-"))
{
this.CompileTerm();
this.block.CompileSend("minus");
return;
}
Token token = this.NextToken();
if (token == null)
{
return;
}
if (token.Type == TokenType.Punctuation && token.Value == ";")
{
this.block.CompileByteCode(ByteCode.ChainedSend);
return;
}
if (token.Type == TokenType.Punctuation && token.Value == "(")
{
this.CompileExpression();
token = this.NextToken();
if (token == null || token.Value != ")")
{
throw new ParserException("')' expected");
}
return;
}
if (token.Type == TokenType.Punctuation && token.Value == "#(")
{
this.block.CompileGetConstant(this.CompileCollection());
return;
}
if (token.Type == TokenType.Punctuation && token.Value == "#[")
{
this.CompileByteCollection();
return;
}
if (token.Type == TokenType.Punctuation && token.Value == "{")
{
this.CompileDynamicCollection();
return;
}
if (token.Type == TokenType.Punctuation && token.Value == "[")
{
Parser newcompiler = new Parser(this.tokenizer);
newcompiler.outer = this.block;
// TODO Review is the copy of argument and local names is needed or use outer block
newcompiler.arguments = new ArrayList(this.arguments);
newcompiler.locals = new ArrayList(this.locals);
Block newblock = newcompiler.CompileBlock();
this.block.CompileGetBlock(newblock);
return;
}
if (token.Type == TokenType.Integer)
{
long value = 0;
int position = token.Value.IndexOf('r');
if (position > 0)
{
string strradix = token.Value.Substring(0, position);
string strnumber = token.Value.Substring(position + 1);
value = Convert.ToInt64(strnumber, Convert.ToInt32(strradix));
}
else
value = Convert.ToInt64(token.Value);
if (value > int.MaxValue || value < int.MinValue)
this.block.CompileGetConstant(value);
else
this.block.CompileGetConstant((int)value);
return;
}
if (token.Type == TokenType.Real)
{
this.block.CompileGetConstant(Convert.ToDouble(token.Value));
return;
}
if (token.Type == TokenType.String)
{
this.block.CompileGetConstant(token.Value);
return;
}
// TODO Review compile of Symbol
if (token.Type == TokenType.Symbol)
{
this.block.CompileGetConstant(token.Value);
return;
}
if (token.Type == TokenType.Character)
{
this.block.CompileGetConstant(token.Value[0]);
return;
}
if (token.Type == TokenType.Name)
{
this.block.CompileGet(token.Value);
return;
}
if (token.Type == TokenType.DottedName)
{
string[] names = token.Value.Split('.');
this.block.CompileByteCode(ByteCode.GetGlobalVariable, (byte)this.block.CompileGlobal(names[0]));
foreach (var name in names.Skip(1))
{
this.block.CompileGetConstant(name);
this.block.CompileSend("at:");
}
return;
}
if (token.Type == TokenType.Operator && token.Value == "<" && this.TryCompileToken(TokenType.Name, "primitive:"))
{
int? number = this.TryCompileInteger();
if (number.HasValue)
{
string error = null;
if (this.TryCompileToken(TokenType.Name, "error:"))
error = this.CompileName();
this.CompileToken(TokenType.Operator, ">");
if (error != null)
this.block.CompileByteCode(ByteCode.PrimitiveError, (byte)number.Value, (byte)this.block.CompileConstant(error));
else
this.block.CompileByteCode(ByteCode.Primitive, (byte)number.Value);
return;
}
string name = this.CompileString();
this.CompileToken(TokenType.Name, "module:");
string module = this.CompileString();
this.CompileToken(TokenType.Operator, ">");
this.block.CompileByteCode(ByteCode.NamedPrimitive, this.block.CompileConstant(name), this.block.CompileConstant(module));
return;
}
throw new ParserException("Name expected");
}