import * as AST from "../../ast/expression" ; import * as GML from "../../graphml/" ; import { nodeFromExpression } from "../create" ; import { StreamPort } from "../ports/stream" ; import { FlatScope } from "../scopes/flat" ; import { Scope } from "../scopes/scope" ; import * as Types from "../types" ; import { checkType } from "../types/check" ; import * as Values from "../values" ; import { Node , subGraphML } from "./node" ; export class FunctionCall extends Node { private nodes : Node [ ] ; private functionBody : Node [ ] ; private callScope ? : FlatScope ; constructor ( functionSource , defintion , scope ) { super ( "FunctionCall" , defintion ) ; this . nodes = [ ] ; this . nodes . push ( functionSource ) ; for ( const expression of defintion . arguments ) { this . nodes . push ( nodeFromExpression ( expression , scope ) ) ; } this . addInPorts ( this . nodes ) ; this . functionBody = [ ] ; this . outPorts = [ ] ; } public requestPorts ( portNum ) { for ( let i = 0 ; i < portNum ; i ++ ) { this . outPorts = [ new StreamPort ( ( type , offset ) => this . fetchData ( i , type , offset ) ) ] ; } return portNum ; } public fetchData ( portNum , type , offset ) { if ( this . callScope ) { return this . fetchReadyData ( portNum , type , offset ) ; } const args = [ ] ; for ( let i = 1 ; i < this . inPorts . length ; i ++ ) { args . push ( this . inPorts [ i ] . getData ( new Types . Some ( ) ) . type ) ; } const returns = this . outPorts . map ( ( ) => new Types . Some ( ) ) ; returns [ portNum ] = type ; const value = this . inPorts [ 0 ] . getData ( new Types . Function ( args , returns ) ) ; if ( value instanceof Values . ErrorValue ) { return new Values . ErrorValue ( "Cannot fetch function body" ) ; } const functionValue = value as Values . Function ; this . callScope = new FlatScope ( functionValue . scope ) ; this . functionBody = functionValue . bodyFactory ( this . callScope ) ; for ( let i = 0 ; i < functionValue . argumentNames . length ; i ++ ) { this . callScope . inject ( functionValue . argumentNames [ i ] , this . inPorts [ i + 1 ] ) ; } return this . fetchReadyData ( portNum , type , offset ) ; } public graphML ( ) { return this . graphMLInternal ( GML . makeGraph ( "function" , subGraphML ( this . functionBody ) ) ) ; } private fetchReadyData ( portNum , type , offset ) { return this . functionBody [ portNum ] . outPorts [ 0 ] . getData ( type , offset ) ; } }