Beispiel #1
0
func verifyInnerStatements(innerStatements []Statement, line int) parser.SyntaxError {
	numOfStatements := len(innerStatements)
	if numOfStatements == 0 {
		return parser.NewSyntaxError("No inner statement found", line, 0)
	} else if _, ok := innerStatements[numOfStatements-1].(*ReturnStatement); !ok {
		return parser.NewSyntaxError("Last statement in function is not a returnable statement", line, 0)
	} else {
		for _, s := range innerStatements[:numOfStatements-1] {
			if _, ok := s.(*LetStatement); !ok {
				return parser.NewSyntaxError("Only the last statement in function can be a returnable statement", line, 0)
			}
		}
	}

	return nil
}
Beispiel #2
0
func ToRpn(line string, lineNum int, fm FunctionMap) ([]RpnValue, parser.SyntaxError) {
	rpn, err := toRpn(line, []RpnValue{}, []RpnValue{}, fm)
	if err != nil {
		return nil, parser.NewSyntaxError(err.Error(), lineNum, 0)
	}

	return rpn, nil
}
Beispiel #3
0
func (fs LambdaStatement) Parse(block string, lineNum int, nextBlockScanner *parser.ScanPeeker, factory *StatementFactory) (Statement, parser.SyntaxError) {
	lines := parser.Lines(block)
	factory = fetchNewFactory(factory)
	typeDef, err, rest := expressionParsing.ParseTypeDef(lines[0])
	if err != nil {
		return nil, parser.NewSyntaxError(err.Error(), lineNum, 0)
	}

	var ftd expressionParsing.FuncTypeDefinition
	var ok bool
	if ftd, ok = typeDef.(expressionParsing.FuncTypeDefinition); !ok {
		return nil, nil
	}

	var codeBlock []string
	if len(strings.TrimSpace(rest)) > 0 {
		var first string
		if len(lines) > 1 {
			return nil, parser.NewSyntaxError("Inline lambdas can only be one line", lineNum, 0)
		} else if first, rest = parser.Tokenize(rest); first != "->" {
			return nil, parser.NewSyntaxError("Misplaced tokens: "+rest, lineNum, 0)
		}
		codeBlock = []string{rest}
	} else {
		codeBlock = parser.RemoveTabs(lines[1:])
	}

	innerStatements, synErr := fetchInnerStatements(codeBlock, factory, lineNum+1)
	if synErr != nil {
		return nil, synErr
	}

	synErr = verifyInnerStatements(innerStatements, lineNum)
	if synErr != nil {
		return nil, synErr
	}

	return newLambdaStatement(lineNum, ftd, innerStatements, fs.packageLevel, fs.name), nil
}
Beispiel #4
0
func ToGoExpression(line string, lineNum int, fm FunctionMap) (string, TypeDefinition, parser.SyntaxError) {
	rpn, synErr := ToRpn(line, lineNum, fm)
	if synErr != nil {
		return "", nil, synErr
	}

	result, td, err := ToInfix(rpn, fm)
	if err != nil {
		return "", nil, parser.NewSyntaxError(err.Error(), lineNum, 0)
	}

	return result, td, nil
}
Beispiel #5
0
func (sf *StatementFactory) Read(blockPeeker *parser.ScanPeeker) (Statement, parser.SyntaxError) {
	ok, value, lineNum := blockPeeker.Read()

	if !ok {
		if blockPeeker.Err() != nil {
			return nil, parser.NewSyntaxError(blockPeeker.Err().Error(), lineNum, 0)
		}
		return nil, nil
	}

	for _, s := range sf.statements {
		statement, err := s.Parse(value, lineNum, blockPeeker, sf)
		if err != nil {
			return nil, err
		} else if statement != nil {
			return statement, nil
		}
	}

	return nil, nil
}
Beispiel #6
0
func writeGeneratedBlocks(factory *statementTypes.StatementFactory, peeker *parser.ScanPeeker, fm expressionParsing.FunctionMap, writer io.Writer) parser.SyntaxError {
	s, synErr := factory.Read(peeker)
	if synErr != nil {
		return synErr
	}

	if s != nil {
		code, _, synErr := s.GenerateGo(fm)
		if synErr != nil {
			return synErr
		}

		_, err := io.WriteString(writer, code+"\n\n")

		if err != nil {
			return parser.NewSyntaxError(err.Error(), 0, 0)
		}
		return writeGeneratedBlocks(factory, peeker, fm, writer)
	}

	return nil
}
Beispiel #7
0
func (ds LetStatement) Parse(block string, lineNum int, nextBlockScanner *parser.ScanPeeker, factory *StatementFactory) (Statement, parser.SyntaxError) {
	lines := parser.Lines(block)

	ok, varName, restOfLine := splitEquals(lines[0])

	if ok {
		if ds.packageLevel {
			factory = adjustFactory(varName, factory)
		}
		combinedLine := parser.FromLines(append([]string{restOfLine}, lines[1:]...))
		peeker := parser.NewScanPeekerStr(combinedLine, lineNum)
		st, err := factory.Read(peeker)
		if err != nil {
			return nil, err
		}
		return newLetStatement(varName, combinedLine, lineNum, st), nil
	}

	if ds.packageLevel {
		return nil, parser.NewSyntaxError(fmt.Sprintf("Unknown statement: %s", lines[0]), lineNum, 0)
	} else {
		return nil, nil
	}
}
Beispiel #8
0
func (ds *LetStatement) GenerateGo(fm expressionParsing.FunctionMap) (string, expressionParsing.TypeDefinition, parser.SyntaxError) {
	innerCode, returnType, synErr := ds.innerStatement.GenerateGo(fm.NextScopeLayer())

	if synErr != nil {
		return "", nil, synErr
	}

	name, err := fm.AddFunction(ds.varName, returnType)
	if err != nil {
		return "", nil, parser.NewSyntaxError(err.Error(), 0, 0)
	}

	var genCode string
	if _, ok := returnType.(expressionParsing.FuncTypeDefinition); ok {
		if ls, ok := ds.innerStatement.(*LambdaStatement); ok && ls.packageLevel {
			genCode = innerCode
		} else {
			genCode = fmt.Sprintf("var %s %s\n%s = %s", name, returnType.GenerateGo(), name, innerCode)
		}
	} else {
		genCode = fmt.Sprintf("var %s func() %s\n%s = func(){\n\treturn %s\n}", name, returnType.GenerateGo(), name, innerCode)
	}
	return genCode, returnType, nil
}