Exemple #1
0
// STRUCT_FIELD         -> TYPE name [ordinal] [equals DEFAULT_VALUE] semi
// DEFAULT_VALUE        -> APPROPRIATE_VAL_SPEC | default
// APPROPRIATE_VAL_SPEC -> VALUE_REF {{that resolves to a type that is assignment compatible to the type of the assignee}}
func (p *Parser) parseStructField(attributes *mojom.Attributes) *mojom.StructField {
	if !p.OK() {
		return nil
	}
	p.pushChildNode("structField")
	defer p.popNode()

	fieldType := p.parseType()
	fieldName := p.readName()
	nameToken := p.lastConsumed
	p.attachToken()

	ordinalValue, err := p.readOrdinal()
	if err != nil {
		p.err = p.newInvalidOrdinalError("field", fieldName, nameToken, err)
		return nil
	}

	var defaultValue mojom.ValueRef
	var defaultValueToken lexer.Token
	if p.tryMatch(lexer.Equals) {
		defaultValueToken = p.peekNextToken("Expecting a default value.")
		if defaultValueToken.Kind == lexer.Default {
			p.consumeNextToken()
			defaultValue = mojom.MakeDefaultLiteral()
		} else {
			defaultValue = p.parseValue(fieldType)
		}
	}
	if !p.matchSemicolon() {
		return nil
	}

	declData := p.DeclDataWithOrdinal(fieldName, nameToken, attributes, ordinalValue)
	field := mojom.NewStructField(declData, fieldType, defaultValue)
	if !field.ValidateDefaultValue() {
		valueString := fmt.Sprintf("%v", defaultValue)
		valueTypeString := ""
		concreteValue := defaultValue.ResolvedConcreteValue()
		if concreteValue != nil {
			valueString = fmt.Sprintf("%v", concreteValue.Value())
			valueTypeString = fmt.Sprintf(" of type %s", concreteValue.ValueType())
		}
		message := fmt.Sprintf("Illegal assignment at %s: Field %s of type %s may not be assigned the value %v%s.",
			defaultValueToken.LongLocationString(), fieldName, fieldType, valueString, valueTypeString)
		p.err = &ParseError{ParserErrorCodeNotAssignmentCompatible, message}
		return nil
	}

	return field
}
// STRUCT_FIELD         -> TYPE name [ordinal] [equals DEFAULT_VALUE] semi
// DEFAULT_VALUE        -> APPROPRIATE_VAL_SPEC | default
// APPROPRIATE_VAL_SPEC -> VALUE_REF {{that resolves to a type that is assignment compatible to the type of the assignee}}
func (p *Parser) parseStructField(attributes *mojom.Attributes) *mojom.StructField {
	if !p.OK() {
		return nil
	}
	p.pushChildNode("structField")
	defer p.popNode()

	fieldType := p.parseType()
	fieldName := p.readName()
	p.attachToken()
	ordinalValue := p.readOrdinal()
	var defaultValue mojom.ValueRef
	var defaultValueToken lexer.Token
	if p.tryMatch(lexer.EQUALS) {
		defaultValueToken = p.peekNextToken("Expecting a default value.")
		if defaultValueToken.Kind == lexer.DEFAULT {
			p.consumeNextToken()
			defaultValue = mojom.MakeDefaultLiteral()
		} else {
			defaultValue = p.parseValue(fieldType)
		}
	}
	if !p.matchSemicolon() {
		return nil
	}

	field := mojom.NewStructField(fieldType, fieldName, ordinalValue, attributes, defaultValue)
	if !field.ValidateDefaultValue() {
		valueString := fmt.Sprintf("%v", defaultValue)
		valueTypeString := ""
		concreteValue := defaultValue.ResolvedConcreteValue()
		if concreteValue != nil {
			valueString = fmt.Sprintf("%v", concreteValue.Value())
			valueTypeString = fmt.Sprintf(" of type %s", concreteValue.ValueType())
		}
		message := fmt.Sprintf("Illegal assignment at %s: Field %s of type %s may not be assigned the value %v%s.",
			defaultValueToken.LongLocationString(), fieldName, fieldType, valueString, valueTypeString)
		p.err = &ParseError{E_TYPE_NOT_ASSIGNMENT_COMPATIBLE, message}
		return nil
	}

	return field
}