7f645807创建于 2025年10月27日历史提交
// Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
// This source file is part of the Cangjie project, licensed under Apache-2.0
// with Runtime Library Exception.
//
// See https://cangjie-lang.cn/pages/LICENSE for license information.

// The Cangjie API is in Beta. For details on its capabilities and limitations, please refer to the README file.

// This is actually a package format
namespace PackageFormat;

// Module
file_identifier "CJOF";

// We expect the loader to redo the symbol table
// but not type inference / check within a loaded module

// Using 'uint32' as type of 'SemaTy/Decl/Expr' 's table index.
// 0 is invalid index, valid index start from 1, which is the offset of table plus 1.
// Because of the size of AST node and 'Ty', length of uint32 is enough that oom will occurred before out-of-range.
enum DeclKind : uint16 {
  InvalidDecl,
  ClassDecl,
  InterfaceDecl,
  FuncDecl,
  PropDecl,
  VarDecl,
  VarWithPatternDecl,
  FuncParam,
  StructDecl,
  EnumDecl,
  ExtendDecl,
  TypeAliasDecl,
  GenericParamDecl,
  BuiltInDecl,
}

// Position member's max length same as 'struct Position''s definition.
struct Position {
  file:uint32;
  pkgId:uint32; // Package's index that file beglongs to. 0 indicates current package
  line:int32;
  column:int32;
  ignore:bool;
}

table FullId {
  pkgId:int32;  // package that the decl belongs to
  decl:string;  // exportId of refed node in other package
  index:uint32; // index of referenced decl in same package
}

table Constraint {
  begin:Position;
  end:Position;
  type:uint32; // type of corresponding typeParameter
  uppers:[uint32]; // UpperBounds
}

table Generic{
  typeParameters:[uint32]; // GenericParamDecls
  constraints:[Constraint];
}

table FuncParamList {
  params:[uint32];
  desugars:[uint32];
}

table FuncBody {
  paramLists:[FuncParamList];
  retType:uint32;
  body:uint32; // index of body expr
  always:bool;
  captureKind:uint8;
}

struct DeclHash {
  instVar:uint64;
  virt:uint64;
  sig:uint64;
  srcUse:uint64;
  bodyHash:uint64;
}

union ConstValue {
  Int8Value,
  UInt8Value,
  Int16Value,
  UInt16Value,
  Int32Value,
  UInt32Value,
  Int64Value,
  UInt64Value,
  Float32Value,
  Float64Value,
  ArrayValue,
  StringValue:string,
  CompositeValue:CompositeValueIndex,
}
struct Int8Value { val:int8; }
struct UInt8Value { val:uint8; }
struct Int16Value { val:int16; } // alse represents Float16
struct UInt16Value { val:uint16; }
struct Int32Value { val:int32; }
struct UInt32Value { val:uint32; }
struct Int64Value { val:int64; }
struct UInt64Value { val:uint64; }
struct Float32Value { val:float32; }
struct Float64Value { val:float64; }
table ArrayValue { val:[ConstValue]; }
struct CompositeValueIndex { idx:uint32; }
table MemberValue {
  field:string;
  type:uint32;
  value:ConstValue;
}
table CompositeValue { // represents class, struct, tuple, enum
  type:uint32;
  fields:[MemberValue];
}

table AutoDiffInfo {
  isDiff:bool;
  isAdj:bool;
  primal:string;
  excepts:[string];
  includes:[string];
  stage:uint64;
}
table ClassInfo {
  inheritedTypes:[uint32];
  body:[uint32];
  adInfo:AutoDiffInfo;
  isAnno:bool = false; // indicates if current class is custom annotation
  annoTargets:uint8;   // available if current class is custom annotation
  runtimeVisible:bool;
  annoTargets2:uint8;
}
table InterfaceInfo {
  inheritedTypes:[uint32];
  body:[uint32];
}
table StructInfo {
  inheritedTypes:[uint32];
  body:[uint32];
  adInfo:AutoDiffInfo;
}
table EnumInfo {
  inheritedTypes:[uint32];
  body:[uint32];
  adInfo:AutoDiffInfo;
  hasArguments:bool;
  nonExhaustive:bool;
  ellipsisPos:Position;
}
table ExtendInfo {
  inheritedTypes:[uint32];
  body:[uint32];
}
table VarInfo {
  isVar:bool;
  isConst:bool;
  isMemberParam:bool;
  initializer:uint32; // Index of expression
  value:ConstValue;   // Has value if it is constant
}
table VarWithPatternInfo {
  isVar:bool;
  isConst:bool;
  irrefutablePattern:Pattern; // Only existed in expression child node.
  initializer:uint32;         // Index of expression
}
enum OverflowPolicy : uint8 {
  NA,
  Checked,
  Wrapping,
  Throwing,
  Saturating,
}
enum OperatorKind : uint8 {
  NA,
  // Overloadable
  Index, // []
  Call,  // ()
  Not,   // !
  Power,     // **
  Multiply,  // *
  Divide,    // /
  Remainder, // %
  Add,       // +
  Subtract,  // -
  BitLeftShift,  // <<
  BitRightShift, // >>
  LT,       // <
  LE,       // <=
  GT,       // >
  GE,       // >=
  Equal,    // ==
  NotEqual, // !=
  BitAnd,   // &
  BitXor,   // ^
  BitOr,    // |

  // Others
  PostInc,     // ++
  PostDec,     // --
  Is,          // is
  As,          // as
  LogicAnd,    // &&
  LogicOr,     // ||
  Coalescing,  // ??
  Pipeline,    // |>
  Composition, // ~>
  Assign,      // =
  PowerAssign,      // **=
  MultiplyAssign,   // *=
  DivideAssign,     // /=
  RemainderAssign,  // %=
  AddAssign,        // +=
  SubtractAssign,   // -=
  LeftShiftAssign,  // <<=
  RightShiftAssign, // >>=
  BitAndAssign,     // &=
  BitXorAssign,     // ^=
  BitOrAssign,      // |=
  LogicAndAssign,   // &&=
  LogicOrAssign,    // ||=
}
table FuncInfo {
  funcBody:FuncBody;
  overflowPolicy:OverflowPolicy;
  op:OperatorKind = NA;
  adInfo:AutoDiffInfo;
  isConst:bool;
  isInline:bool;
  isFastNative:bool;
}
table ParamInfo {
  isNamedParam:bool;
  isMemberParam:bool;
  defaultVal:uint32; // Index of expression
}
table PropInfo {
  isConst:bool;
  isMutable:bool;
  setters:[uint32];
  getters:[uint32];
}
enum BuiltInType : uint8 {
  Array,
  VArray,
  CPointer,
  CString,
  CFunc,
}
table BuiltInInfo {
  builtInType:BuiltInType;
}
table AliasInfo {
  aliasedTy:uint32; // Index of semantic type
}
union DeclInfo {
  ClassInfo,
  InterfaceInfo,
  StructInfo,
  EnumInfo,
  ExtendInfo,
  PropInfo,
  VarInfo,
  VarWithPatternInfo,
  ParamInfo,
  FuncInfo,
  BuiltInInfo,
  AliasInfo,
}

table Decl {
  kind:DeclKind = InvalidDecl;
  isTopLevel:bool = false; // whether the decl is toplevel
  fullPkgName:string;
  genericDecl:FullId;
  generic:Generic;
  begin:Position;
  end:Position;
  identifier:string;
  identifierPos:Position;
  attributes:[uint64];
  annotations:[Anno];

  // Semantic & CodeGen info
  type: uint32;
  mangledName: string; // mangledName for CodeGen
  exportId: string;    // exportId for import

  // info used in ast diff
  mangledBeforeSema:string;
  hash:DeclHash;
  // Specific information for each specific kind of declaration
  info:DeclInfo;
}

enum AnnoKind : uint16 {
  Deprecated,
  TestRegistration,
  Frozen,
  Custom
}

// Current annotation representation is a balance between needs of @Deprecated
// and potential generalization for other annotations
table Anno { // Short name "Anno" because of the clash with "Annotation" from "PackageFormat.fbs"
  kind:AnnoKind;
  identifier:string;
  args:[AnnoArg];
}

table AnnoArg {
  name:string;
  expr:uint32; // index of Expr (LitConstExpr)
}

enum ExprKind : uint16 {
  InvalidExpr,
  WildcardExpr,
  PrimitiveTypeExpr,
  ReturnExpr,
  JumpExpr,
  MemberAccess,
  RefExpr,
  CallExpr,
  UnaryExpr,
  IncOrDecExpr,
  LitConstExpr,
  BinaryExpr,
  SubscriptExpr,
  AssignExpr,
  ArrayExpr,
  PointerExpr,
  TypeConvExpr,
  ThrowExpr,
  SpawnExpr,
  ArrayLit,
  TupleLit,
  MatchExpr,
  LetPatternDestructor,
  IfExpr,
  TryExpr,
  WhileExpr,
  DoWhileExpr,
  LambdaExpr,
  Block,
  MatchCase,
  MatchCaseOther,
  AdjointExpr,
  GradExpr,
  ValWithGradExpr,
  VJPExpr,
  ForInExpr,
  IfAvailableExpr,
  PerformExpr,
  ResumeExpr,
}

enum CallKind : uint8 {
  NA,
  CallDeclaredFunction,
  CallObjectCreation,
  CallStructCreation,
  CallSuperFunction,
  CallVariadicFunction,
  CallFunctionPtr,
  CallAnnotation,
  CallBuiltinFunction,
  CallIntrinsicFunction,
}

enum LitConstKind : uint8 {
  Integer,
  RuneByte,
  Float,
  Rune,
  String,
  JString,
  Bool,
  Unit,
}
enum StringKind : uint8 {
  Normal,
  JString,
  MultiLine,
  MultiLineRaw,
}

enum ForInKind : uint8 {
  NA,
  Range,
  String,
  Iterator,
}

union ExprInfo {
  CallInfo,
  UnaryInfo,
  BinaryInfo,
  IncOrDecInfo,
  LitConstInfo,
  ReferenceInfo,
  LambdaInfo,
  AssignInfo,
  ArrayInfo,
  JumpInfo,
  FuncArgInfo,
  SubscriptInfo,
  MatchInfo,
  BlockInfo,
  TryInfo,
  LetPatternDestructorInfo,
  ForInInfo,
  MatchCaseInfo,
  SpawnInfo,
}
table CallInfo {
  hasSideEffect:bool;
  callKind:CallKind = NA;
}
table UnaryInfo {
  op:OperatorKind;
}
table BinaryInfo {
  op:OperatorKind;
}
table IncOrDecInfo {
  op:OperatorKind;
}
table LitConstInfo {
  strValue:string;
  constKind:LitConstKind;
  strKind:StringKind;
}
table ReferenceInfo {
  // For RefExpr/MemberAccess
  reference:string; // also for LitConstExpr string value
  target:FullId;
  instTys:[uint32]; // Instantiated type index vectors.
  matchedParentTy:uint32; // For instantiation re-arrange.
}
table LambdaInfo {
  funcBody:FuncBody (required); // LambdaExpr
  supportMock:bool;
}
table AssignInfo {
  isCompound:bool;
  op:OperatorKind;
}
table ArrayInfo {
  initFunc:FullId;
  isValueArray:bool;
}
table JumpInfo {
  isBreak:bool;
}
table FuncArgInfo {
  withInout:bool;
  isDefaultVal:bool;
}
table SubscriptInfo {
  isTupleAccess:bool;
}
table MatchInfo {
  matchMode:bool;
}
table BlockInfo {
  isExpr:[bool];
}
table TryInfo {
  resources:[FullId]; // for try-with-resource
  patterns:[Pattern];
}
table LetPatternDestructorInfo {
  patterns:[Pattern];
}
table ForInInfo {
  pattern:Pattern;
  forInKind:ForInKind = NA;
}
table MatchCaseInfo {
  patterns:[Pattern];
}
table SpawnInfo {
  future:FullId;
}

table Expr {
  kind:ExprKind = InvalidExpr;
  begin:Position;
  end:Position;
  mapExpr:uint32;    // index of expr to deal with side effect.
  operands:[uint32]; // index of sub expressions
  type:uint32;
  overflowPolicy:OverflowPolicy;
  info:ExprInfo;
}

enum PatternKind:int8 {
  InvalidPattern,
  ConstPattern,
  WildcardPattern,
  VarPattern,
  TuplePattern,
  TypePattern,
  EnumPattern,
  ExceptTypePattern,
  CommandTypePattern,
}

table Pattern {
  kind:PatternKind = InvalidPattern;
  begin:Position;
  end:Position;
  patterns:[Pattern];
  types:[uint32];    // SemaTy indexes.
  exprs:[uint32];
  values:[ConstValue];
  matchBeforeRuntime:bool;
  needRuntimeTypeCheck:bool;
}

// For compatibility any new type kind MUST only be added at last.
enum TypeKind : uint16 {
  Invalid, // invalid

  // primitive type
  Unit, // unit
  // integer
  Int8,
  Int16,
  Int32,
  Int64,
  IntNative,

  // unsigned integer
  UInt8,
  UInt16,
  UInt32,
  UInt64,
  UIntNative,
  // float
  Float16,
  Float32,
  Float64,

  Rune,    // char
  Nothing,
  Bool,    // bool

  // composite type
  Tuple,  // Tuple
  Enum,   // enum
  Func,   // function
  Struct, // struct

  // reference type
  Array,  // Array
  VArray, // VArray
  CPointer,
  CString,
  Class,
  Interface,

  Type,    // typealias
  Generic, // genericTy
}

union SemaTyInfo {
  FuncTyInfo,
  CompositeTyInfo,
  GenericTyInfo,
  ArrayTyInfo,
}
table FuncTyInfo {
  retType:uint32; // Func return type
  isC:bool;       // CFunc or @C func type.
  hasVariableLenArg:bool;
}
table CompositeTyInfo {
  declPtr:FullId;
  isThisTy:bool=false;
}
table GenericTyInfo {
  declPtr:FullId;
  upperBounds:[uint32];
}
table ArrayTyInfo {
  dimsOrSize:int64;
}

table SemaTy {
  kind:TypeKind=Unit;
  // TypeArguments, also for funcTy's paramTypes
  typeArgs:[uint32];
  info:SemaTyInfo;
}

enum AccessModifier : uint8 {
  Private,
  Internal,
  Protected,
  Public,
}

table ImportSpec {
  begin:Position;
  end:Position;
  prefixPaths:[string];
  identifier:string;
  asIdentifier:string;
  reExport:AccessModifier = Private;
}

table Imports {
  importSpecs:[ImportSpec];
}

enum PackageKind : uint8 {
  Normal, // normal package.
  Macro,  // macro package.
  Foreign,   // foreign language package.
  Mock,   // package with mocking support.
}

enum AccessLevel : uint8 {
  Public,
  Protected,
  Internal,
}

struct CjoVersion {
  major_num:uint8;
  minor_num:uint8;
  patch_num:uint8;
}

// all SemaTys, decls are saved here, and indexed by other nodes.
table Package {
  version:string;            // cjc version.
  cjoVersion:CjoVersion;     // cjo format version.
  fullPkgName:string;        // full package name.
  pkgDepInfo:string;         // package dependency info.
  imports:[string];          // all imported packages.
  allFiles:[string];         // all files in package.
  allFileImports:[Imports];  // all file imports in package.
  allTypes:[SemaTy];         // all saved SemaTys.
  allDecls:[Decl];           // all saved decls.
  allExprs:[Expr];           // all saved expressions.
  allValues:[CompositeValue];// all saved constant composite values.
  kind:PackageKind = Normal; // package kind.
  access:AccessLevel = Public;
  moduleName:string;
}

root_type Package;