public ParseContext Parse(IParseTree context, LexicalEnvironment parentEnvironment) { parseContext = new ParseContext(_engine, parentEnvironment); if (_scriptFunction != null) { foreach (var kv in parentEnvironment.Variables) { parseContext.AddVariableReference(kv.Value, VariableReferenceType.Argument); } } Visit(context); parseContext.LexicalEnvironment = parseContext.LexicalEnvironment.Root; return(parseContext); }
public override ParseResult VisitVariableDefinitionStatement(MelonParser.VariableDefinitionStatementContext context) { var expressionResult = Visit(context.expression()); MelonType type; int typeId; TypeReference typeReference = null; if (context.Type != null) { var typeName = context.Type.name().value; var typeKv = _engine.Types.FirstOrDefault(x => x.Value.Name == typeName); if (typeKv.Value == null) { throw new MelonException($"Could not find type '{typeName}'"); } if (typeKv.Value == _engine.voidType) { throw new MelonException($"Cannot assign to void"); } if (expressionResult.typeReference.TypeId != typeKv.Key && typeKv.Key != 0) { throw new MelonException($"Variable of type '{typeName}' can't be assigned to '{expressionResult.typeReference.Type.Name}'"); } typeReference = CreateTypeReference(context.Type); type = typeKv.Value; typeId = typeKv.Key; } else { type = expressionResult.typeReference.Type; typeReference = new TypeReference(_engine, type); if (type == _engine.voidType) { throw new MelonException($"Cannot assign to void"); } typeId = expressionResult.typeReference.TypeId; } var name = context.Name.value; var variable = parseContext.LexicalEnvironment.GetVariable(name); int id; if (expressionResult.value is IGeneric generic) { generic.GenericTypes = typeReference.GenericTypes; } if (variable != null) { throw new MelonException($"Variable '{name}' already defined."); } else { variable = parseContext.LexicalEnvironment.AddVariable(name, expressionResult.value, typeReference); id = parseContext.AddVariableReference(variable, VariableReferenceType.Local); } parseContext.instructions.Add((int)OpCode.STLOC); parseContext.instructions.Add(id); instructionline++; return(DefaultResult); }