visitEnum()

in lib/semantic.js [3406:3438]


  visitEnum(ast) {
    assert.equal(ast.type, 'enum');
    const enumName = ast.enumName.lexeme;

    const enumType = this.getType(ast.enumType);
    // only suport string & number
    if (enumType.type !== 'basic' &&
      enumType.name !== 'string' && !isNumber(enumType.name)) {
      this.error(`enum "${enumName}" has a wrong type, enum only suppot string or number.`);
    }

    for (var i = 0; i < ast.enumBody.nodes.length; i++) {
      const enumAttrs = ast.enumBody.nodes[i].enumAttrs;
      let attrNames = new Map();
      enumAttrs.forEach(attr => {
        if (attrNames.has(attr.attrName.lexeme)) {
          this.error(`the enum attribute "${attr.attrName.lexeme}" is redefined.`);
        }
        attrNames.set(attr.attrName.lexeme, true);
        if (attr.attrName.lexeme === 'value') {
          // enum's value declare just like assign
          const valueType = this.getExprType(attr.attrValue);
          if (!isAssignable(enumType, valueType)) {
            this.error(`the enum types are mismatched. expected ${enumType.name}, but ${valueType.name}`);
          } 
        }
      });
      if (!attrNames.has('value')) {
        this.error(`enum "${enumName}" must have attribute "value".`);
      }
    }
    
  }