github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/compiler/compiler.go (about)

     1  package compiler
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  
     7  	"github.com/nevalang/neva/internal/compiler/sourcecode"
     8  	"github.com/nevalang/neva/internal/runtime/ir"
     9  )
    10  
    11  type Compiler struct {
    12  	builder   Builder
    13  	parser    Parser
    14  	desugarer Desugarer
    15  	analyzer  Analyzer
    16  	irgen     IRGenerator
    17  	backend   Backend
    18  }
    19  
    20  // Compile compiles given rawBuild to target language
    21  // and uses specified backend to emit files to the destination.
    22  func (c Compiler) Compile(
    23  	src string,
    24  	mainPkgName string,
    25  	dstPath string,
    26  ) error {
    27  	ir, err := c.CompileToIR(src, mainPkgName)
    28  	if err != nil {
    29  		return err
    30  	}
    31  	return c.backend.Emit(dstPath, ir)
    32  }
    33  
    34  func (c Compiler) CompileToIR(
    35  	wd string,
    36  	mainPkgPath string,
    37  ) (*ir.Program, *Error) {
    38  	rawBuild, entryModRoot, err := c.builder.Build(
    39  		context.Background(),
    40  		mainPkgPath,
    41  	)
    42  	if err != nil {
    43  		return nil, Error{
    44  			Location: &sourcecode.Location{
    45  				PkgName: mainPkgPath,
    46  			},
    47  		}.Wrap(err)
    48  	}
    49  
    50  	parsedMods, err := c.parser.ParseModules(rawBuild.Modules)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	parsedBuild := sourcecode.Build{
    56  		EntryModRef: rawBuild.EntryModRef,
    57  		Modules:     parsedMods,
    58  	}
    59  
    60  	mainPkgPath = strings.TrimPrefix(mainPkgPath, "./")
    61  	mainPkgPath = strings.TrimPrefix(mainPkgPath, entryModRoot+"/")
    62  
    63  	analyzedBuild, err := c.analyzer.AnalyzeExecutableBuild(
    64  		parsedBuild,
    65  		mainPkgPath,
    66  	)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	desugaredBuild, err := c.desugarer.Desugar(analyzedBuild)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	irProg, err := c.irgen.Generate(desugaredBuild, mainPkgPath)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  
    81  	return irProg, nil
    82  }
    83  
    84  func New(
    85  	builder Builder,
    86  	parser Parser,
    87  	desugarer Desugarer,
    88  	analyzer Analyzer,
    89  	irgen IRGenerator,
    90  	backend Backend,
    91  ) Compiler {
    92  	return Compiler{
    93  		builder:   builder,
    94  		parser:    parser,
    95  		desugarer: desugarer,
    96  		analyzer:  analyzer,
    97  		irgen:     irgen,
    98  		backend:   backend,
    99  	}
   100  }