import { Value } from '../values.ts'
import { Type, Types } from './types.ts'

/**
 * Calculates the Lore type of a value.
 */
export function typeOf(value: any): Type {
  switch (typeof value) {
    case 'number':
      if (Number.isInteger(value)) {
        return Types.int
      } else {
        return Types.real
      }
    case 'boolean':
      return Types.boolean
    case 'string':
      return Types.string
    case 'object':
      // TODO: In the case of a Javascript object being given that does not have a type field, we should return some
      //       kind of "dynamic" type. Of course, this first requires us to define a similar notion within Lore
      //       itself.
      if (value.hasOwnProperty('lore$type')) {
        return (<Value> value).lore$type
      }
      break
  }

  // TODO: Throw a "corresponding Lore type not found" error.
  return Types.any
}

import { Value } from '../values.ts'
import { Type, Types } from './types.ts'

/**
 * Calculates the Lore type of a value.
 *
 * TODO: If the compiler is sure that a given value is a struct, shape value, etc. with a lore$type attribute,
 *       we should inline the lore$type access to remove the need of calling typeOf. This should bring sizable
 *       performance gains.
 */
export function typeOf(value: any): Type {
  switch (typeof value) {
    case 'number':
      if (Number.isInteger(value)) {
        return Types.int
      } else {
        return Types.real
      }
    case 'boolean':
      return Types.boolean
    case 'string':
      return Types.string
    case 'object':
      // TODO: In the case of a Javascript object being given that does not have a type field, we should return some
      //       kind of "dynamic" type. Of course, this first requires us to define a similar notion within Lore
      //       itself.
      if ((<Value> value).lore$type) {
        return (<Value> value).lore$type
      }
      break
  }

  // TODO: Throw a "corresponding Lore type not found" error.
  return Types.any
}

Remove hasOwnProperty call from typeOf.
Remove hasOwnProperty call from typeOf.

Also note down a potential further optimization to inline typeOf calls if the compiler can sufficiently narrow down an argument's type.
