All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aya.compiler.DataSerializer Maven / Gradle / Ivy

There is a newer version: 0.36.0
Show newest version
// Copyright (c) 2020-2024 Tesla (Yinsen) Zhang.
// Use of this source code is governed by the MIT license that can be found in the LICENSE.md file.
package org.aya.compiler;

import kala.collection.immutable.ImmutableMap;
import kala.collection.immutable.ImmutableSeq;
import kala.tuple.Tuple;
import org.aya.primitive.ShapeFactory;
import org.aya.syntax.compile.JitData;
import org.aya.syntax.core.def.DataDef;
import org.aya.syntax.core.def.TyckAnyDef;
import org.aya.syntax.core.repr.CodeShape;
import org.aya.syntax.ref.DefVar;
import org.jetbrains.annotations.NotNull;

import static org.aya.compiler.AyaSerializer.CLASS_DATACALL;
import static org.aya.compiler.NameSerializer.getClassReference;

// You should compile this with its constructors
public final class DataSerializer extends JitTeleSerializer {
  private final @NotNull ShapeFactory shapeFactory;

  public DataSerializer(@NotNull SourceBuilder builder, @NotNull ShapeFactory shapeFactory) {
    super(builder, JitData.class);
    this.shapeFactory = shapeFactory;
  }

  @Override public DataSerializer serialize(DataDef unit) {
    buildFramework(unit, () -> buildMethod("constructors", ImmutableSeq.empty(),
      CLASS_JITCON + "[]", true,
      () -> buildConstructors(unit)));
    return this;
  }

  @Override protected @NotNull String callClass() { return CLASS_DATACALL; }
  @Override protected void buildShape(DataDef unit) {
    var maybe = shapeFactory.find(TyckAnyDef.make(unit));
    if (maybe.isEmpty()) {
      super.buildShape(unit);
      return;
    }
    var recog = maybe.get();
    appendMetadataRecord("shape", Integer.toString(recog.shape().ordinal()), false);

    // The capture is one-to-one
    var flipped = ImmutableMap.from(recog.captures().view()
      .map((k, v) -> Tuple., CodeShape.GlobalId>of(((TyckAnyDef) v).ref, k)));
    var capture = unit.body.map(x -> ExprializeUtils.makeSub(CLASS_GLOBALID, flipped.get(x.ref).toString()));
    appendMetadataRecord("recognition", ExprializeUtils.makeHalfArrayFrom(capture), false);
  }

  @Override protected void buildConstructor(DataDef unit) {
    buildConstructor(unit, ImmutableSeq.of(Integer.toString(unit.body.size())));
  }

  /**
   * @see JitData#constructors()
   */
  private void buildConstructors(DataDef unit) {
    var cRef = "this.constructors";
    if (unit.body.isEmpty()) {
      buildReturn(cRef);
      return;
    }

    buildIf(ExprializeUtils.isNull(cRef + "[0]"), () ->
      unit.body.forEachIndexed((idx, con) ->
        buildUpdate(cRef + "[" + idx + "]", ExprializeUtils.getInstance(getClassReference(con.ref)))));

    buildReturn(cRef);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy